/* * Copyright 2016 Liam Palmer * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */instanceLowerBound[Int16] {pubdefminValue(): Int16 = Int16.minValue()}instanceUpperBound[Int16] {pubdefmaxValue(): Int16 = Int16.maxValue()}pubmod Int16 {import java.lang.NumberFormatExceptionimport java.lang.Shortimport java.math.BigDecimalimport java.math.BigInteger////// Returns the number of bits used to represent an `Int16`.///pubdefsize(): Int32 = 16////// Returns the minimum number representable by an `Int16`.///pubdefminValue(): Int16 = leftShift(1i16, size()-1)////// Returns the maximum number representable by an `Int16`.///pubdefmaxValue(): Int16 = bitwiseNot(minValue())////// Returns the smaller of `x` and `y`.///pubdefmin(x: Int16, y: Int16): Int16 = if (x<=y) xelsey////// Returns the larger of `x` and `y`.///pubdefmax(x: Int16, y: Int16): Int16 = if (x>=y) xelsey////// Returns the absolute value of `x`./// If the absolute value exceeds maxValue(), -1 is returned.///pubdefabs(x: Int16): Int16 = {if (x>=0i16)xelseif (x==minValue()) -1i16else-x }////// Returns the Euclidean modulo of `x` and `n`./// The result is always non-negative.///pubdefmodulo(x: Int16, n: Int16): Int16 =if (n==0i16)0i16else %%INT16_REM%%(%%INT16_REM%%(x, n) +n, n)////// Returns the remainder of `x / n`./// The result can be negative.////// See also `Int16.modulo`.///pubdefremainder(x: Int16, n: Int16): Int16 =if (n==0i16)0i16else %%INT16_REM%%(x, n)////// Returns the distance between `x` and `y`./// If this distance exceeds maxValue(), -1 is returned.///pubdefdist(x: Int16, y: Int16): Int16 = {if (x>=0i16andy>=0i16)abs(x-y)elseif (x<0i16andy<0i16)abs(x-y)elseif (x==minValue()ory==minValue()) -1i16elseif (minValue()+abs(x) +abs(y) >=0i16) -1i16elseabs(x-y) }////// Returns 1 if x > y, -1 if x < y, and 0 if x = y./// The sign of x - y.///pubdefcompare(x: Int16, y: Int16): Int32 = {if (x==y)0elseif (x<y) -1else1 }////// Returns 1 if x > 0, -1 if x < 0, and 0 if x = 0./// The sign of x.///pubdefsignum(x: Int16): Int32 = compare(x, 0i16)////// Returns `base` raised to the power of `n`.///pubdefpow(base: {base = Int16}, n: Int16): Int16 = %%INT16_EXP%%(base#base, n)////// Returns the logical right shift of `x` by `distance`./// Only the rightmost 5 bits of `distance` are considered (ie. `distance rem 32`)./// A zero is shifted into the leftmost position regardless of sign extension.///pubdeflogicalRightShift(dist: {dist = Int32}, x: Int16): Int16 =if (x<0i16andInt32.remainder(dist#dist, 32) !=0)rightShift(bitwiseAnd(rightShift(x, 1), maxValue()), dist#dist -1)elserightShift(x, dist#dist)////// Returns the number of one-bits in the two's complement binary/// representation of `x`.///pubdefbitCount(x: Int16): Int32 = {if (x==0i16)0elseif (x`remainder`2i16!=0i16)bitCount(logicalRightShift(dist = 1, x)) +1elsebitCount(logicalRightShift(dist = 1, x)) }////// Returns the value obtained by rotating the two's complement/// binary representation of `x` right by `distance` bits.///pubdefrotateRight(dist: {dist = Int32}, x: Int16): Int16 =letrem1 = dist#dist `Int32.remainder`size();letrot = if (rem1>=0) rem1elserem1+size();bitwiseOr(logicalRightShift(dist = rot, x), leftShift(x, size()-rot))////// Returns the value obtained by rotating the two's complement/// binary representation of `x` left by `distance` bits.///pubdefrotateLeft(dist: {dist = Int32}, x: Int16): Int16 =letrem1 = dist#dist `Int32.remainder`size();letrot = if (rem1>=0) rem1elserem1+size();bitwiseOr(logicalRightShift(dist = size()-rot, x), leftShift(x, rot))////// Returns the value obtained by reversing the bits in the/// two's complement binary representation of `x`.///pubdefreverse(x: Int16): Int16 = reverseHelper(x, 0, size()-1)////// Helper function for `reverse`.///defreverseHelper(x: Int16, l: Int32, r: Int32): Int16 =if (l>=r) xelsereverseHelper(swap(x, l, r), l+1, r-1)////// Helper function for `reverse`.///defswap(x: Int16, l: Int32, r: Int32): Int16 = match (getBit(pos = l, x), getBit(pos = r, x)) {case (1, 0) => clearBit(pos = l, setBit(pos = r, x))case (0, 1) => clearBit(pos = r, setBit(pos = l, x))case_ => x }////// Returns the position of the highest-order/leftmost one-bit in `x`./// Possible return values: 0 (rightmost bit) - 15 (leftmost bit)/// -1 if x = 0///pubdefhighestOneBitPosition(x: Int16): Int32 =// Start at bit 15 and scan rightoneBitPositionHelper(x, size()-1, -1)////// Returns the position of the lowest-order/rightmost one-bit in `x`./// Possible return values: 0 (rightmost bit) - 15 (leftmost bit)/// -1 if x = 0///pubdeflowestOneBitPosition(x: Int16): Int32 =// Start at bit 0 and scan leftoneBitPositionHelper(x, 0, 1)////// Helper function for highestOneBitPosition and lowestOneBitPosition./// If `x` has a one-bit at `position`, return that position./// Otherwise recursively check the next bit in the same way.///defoneBitPositionHelper(x: Int16, position: Int32, delta: Int32): Int32 = {if (position<0) -1elseif (position> (size()-1)) -1elseif (getBit(pos = position, x) ==1)positionelseif (delta==0) -1elseoneBitPositionHelper(x, position+delta, delta) }////// Returns a value with at most a single one-bit, in the position/// of the highest-order/leftmost one-bit in `x`./// Returns 0 if x=0.///pubdefhighestOneBit(x: Int16): Int16 =bitPositionToInt16(highestOneBitPosition(x))////// Returns a value with at most a single one-bit, in the position/// of the highest-order/leftmost one-bit in `x`./// Returns 0 if x=0.///pubdeflowestOneBit(x: Int16): Int16 =bitPositionToInt16(lowestOneBitPosition(x))////// Helper function for highestOneBit and lowestOneBit./// Returns a value with a single one-bit at bit number `position`./// Returns 0 if `position` is outside the range 0-15 inclusive.///defbitPositionToInt16(position: Int32): Int16 =if (position<0orposition>size()-1) 0i16elseleftShift(1i16, position)////// Returns the number of zero bits preceding the/// highest-order/leftmost one-bit in `x`./// Returns 16 if x=0.///pubdefnumberOfLeadingZeros(x: Int16): Int32 =if (x==0i16) size()elsesize()-1-highestOneBitPosition(x)////// Returns the number of zero bits following the/// lowest-order/rightmost one-bit in `x`./// Returns 16 if x=0.///pubdefnumberOfTrailingZeros(x: Int16): Int32 =if (x==0i16) size()elselowestOneBitPosition(x)////// Returns the bit of `x` at `pos` (either 0 or 1)./// Considers the 5 rightmost bits of `pos` (`pos` modulo 32)./// The bits of x have positions: 0 (rightmost bit) - 15 (leftmost bit)///pubdefgetBit(pos: {pos = Int32}, x: Int16): Int32 =if (rightShift(x, pos#pos) `remainder`2i16==0i16) 0else1////// Returns `x` with the bit at position `pos` set (to 1)./// Considers the 5 rightmost bits of `pos` (`pos` modulo 32)./// The bits of x have positions: 0 (rightmost bit) - 15 (leftmost bit)///pubdefsetBit(pos: {pos = Int32}, x: Int16): Int16 = bitwiseOr(x, leftShift(1i16, pos#pos))////// Returns `x` with the bit at position `pos` cleared (to 0)./// Considers the 5 rightmost bits of `pos` (`pos` modulo 32)./// The bits of x have positions: 0 (rightmost bit) - 15 (leftmost bit)///pubdefclearBit(pos: {pos = Int32}, x: Int16): Int16 = bitwiseAnd(x, bitwiseNot(leftShift(1i16, pos#pos)))////// Returns `x` with the bit at position `pos` flipped./// Considers the 5 rightmost bits of `pos` (`pos` modulo 32)./// The bits of x have positions: 0 (rightmost bit) - 15 (leftmost bit)///pubdefflipBit(pos: {pos = Int32}, x: Int16): Int16 = bitwiseXor(x, leftShift(1i16, pos#pos))////// Returns the integer binary logarithm of `x`./// If the given value is 0 or negative, 0 is returned.///pubdeflog2(x: Int16): Int16 =if (x<=0i16) {0i16 } else {letposition = highestOneBitPosition(x);Int32.clampToInt16(min = 0i16, max = Int16.maxValue(), position) }////// Returns `x` with the bits shifted left by `y` places///pubdefleftShift(x: Int16, y: Int32): Int16 = %%INT16_SHL%%(x, y)////// Returns `x` with the bits shifted right by `y` places///pubdefrightShift(x: Int16, y: Int32): Int16 = %%INT16_SHR%%(x, y)////// Returns the bitwise AND of `x` and `y`.///pubdefbitwiseAnd(x: Int16, y: Int16): Int16 = %%INT16_AND%%(x, y)////// Returns the bitwise NOT of `x`.///pubdefbitwiseNot(x: Int16): Int16 = %%INT16_NOT%%(x)////// Returns the bitwise OR of `x` and `y`.///pubdefbitwiseOr(x: Int16, y: Int16): Int16 = %%INT16_OR%%(x, y)////// Returns the bitwise XOR of `x` and `y`.///pubdefbitwiseXor(x: Int16, y: Int16): Int16 = %%INT16_XOR%%(x, y)////// Returns the factorial of `x`.///pubdeffactorial(x: Int16): Int32 = toInt32(x) |> Int32.factorial////// Return a string representation of `x`.///pubdeftoString(x: Int16): String = ToString.toString(x)////// Parse the string `s` as an Int16, leading or trailing whitespace is trimmed./// A successful parse is wrapped with `Some(x)`, a parse failure is indicated by `None`.///pubdeffromString(s: String): Option[Int16] = try { Some(Short.parseShort(s.strip())) } catch {case_: NumberFormatException => None }////// Convert `x` to an `Option[Int8]`.////// Returns `Some(x as Int8)` if the numeric value of `x` can be represented exactly.////// Returns `None` if the numeric value of `x` is outside the range of Int8/// (i.e. -128 to 127).///pubdeftryToInt8(x: Int16): Option[Int8] =if (x<Int8.toInt16(Int8.minValue()) orx>Int8.toInt16(Int8.maxValue())) Noneelse Some(Short.valueOf(x).byteValue())////// Convert `x` to a Int32.////// The numeric value of `x` is preserved exactly.///pubdeftoInt32(x: Int16): Int32 = Short.valueOf(x).intValue()////// Convert `x` to a Int64.////// The numeric value of `x` is preserved exactly.///pubdeftoInt64(x: Int16): Int64 = Short.valueOf(x).longValue()////// Convert `x` to a BigInt.////// The numeric value of `x` is preserved exactly.///pubdeftoBigInt(x: Int16): BigInt = BigInteger.valueOf(Short.valueOf(x).longValue())////// Convert `x` to a Float32.////// The numeric value of `x` is preserved exactly.///pubdeftoFloat32(x: Int16): Float32 = Short.valueOf(x).floatValue()////// Convert `x` to a Float64.////// The numeric value of `x` is preserved exactly.///pubdeftoFloat64(x: Int16): Float64 = Short.valueOf(x).doubleValue()////// Convert `x` to a BigDecimal.////// The numeric value of `x` is preserved exactly.///pubdeftoBigDecimal(x: Int16): BigDecimal =new BigDecimal(Int16.toInt32(x))////// Helper function for the `clamp` conversion function.///defclamp(min: {min = Int16}, max: {max = Int16}, x: Int16): Int16 =if (x<min#min)min#minelseif (x>max#max)max#maxelsex////// Convert `x` to an `Int8`.////// Returns `x` clamped within the Int8 range `min` to `max`.///pubdefclampToInt8(min: {min = Int8}, max: {max = Int8}, x: Int16): Int8 =letmini16 = Int8.toInt16(min#min);letmaxi16 = Int8.toInt16(max#max); Short.valueOf(clamp(min = mini16, max = maxi16, x)).byteValue()////// Convert `x` to an Int8 by truncation.////// Discards all but the lowest 8 bits.///pubdeftruncateToInt8(x: Int16): Int8 = Short.valueOf(x).byteValue()////// Get the primitive Int16 value from its object representation (i.e. Short).////// This function is expected to be used when marshaling Int16s from Java. Generally in Flix/// code you should not need to use `Short`.///pubdefshortValue(i: Short): Int16 =i.shortValue()////// Convert an Int16 value to its object representation (i.e. Short).////// This function is expected to be used when marshaling Int16s to Java. Generally in Flix/// code you should not need to use `Short`.///pubdefvalueOf(i: Int16): Short = Short.valueOf(i)}