/* * 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[Int64] {pubdefminValue(): Int64 = Int64.minValue()}instanceUpperBound[Int64] {pubdefmaxValue(): Int64 = Int64.maxValue()}pubmod Int64 {import java.lang.Longimport java.lang.NumberFormatExceptionimport java.math.BigDecimalimport java.math.BigInteger////// Returns the number of bits used to represent an `Int64`.///pubdefsize(): Int32 = 64////// Returns the minimum number representable by an `Int64`.///pubdefminValue(): Int64 = leftShift(1i64, size()-1)////// Returns the maximum number representable by an `Int64`.///pubdefmaxValue(): Int64 = bitwiseNot(minValue())////// Returns the smaller of `x` and `y`.///pubdefmin(x: Int64, y: Int64): Int64 = if (x<=y) xelsey////// Returns the larger of `x` and `y`.///pubdefmax(x: Int64, y: Int64): Int64 = if (x>=y) xelsey////// Returns the absolute value of `x`./// If the absolute value exceeds maxValue(), -1 is returned.///pubdefabs(x: Int64): Int64 = {if (x>=0i64)xelseif (x==minValue()) -1i64else-x }////// Returns the Euclidean modulo of `x` and `n`./// The result is always non-negative.///pubdefmodulo(x: Int64, n: Int64): Int64 =if (n==0i64)0i64else %%INT64_REM%%(%%INT64_REM%%(x, n) +n, n)////// Returns the remainder of `x / n`./// The result can be negative.////// See also `Int64.modulo`.///pubdefremainder(x: Int64, n: Int64): Int64 =if (n==0i64)0i64else %%INT64_REM%%(x, n)////// Returns the distance between `x` and `y`./// If this distance exceeds maxValue(), -1 is returned.///pubdefdist(x: Int64, y: Int64): Int64 = {if (x>=0i64andy>=0i64)abs(x-y)elseif (x<0i64andy<0i64)abs(x-y)elseif (x==minValue()ory==minValue()) -1i64elseif (minValue()+abs(x) +abs(y) >=0i64) -1i64elseabs(x-y) }////// Returns 1 if x > y, -1 if x < y, and 0 if x = y./// The sign of x - y.///pubdefcompare(x: Int64, y: Int64): 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: Int64): Int32 = compare(x, 0i64)////// Returns `base` raised to the power of `n`.///pubdefpow(base: {base = Int64}, n: Int64): Int64 = %%INT64_EXP%%(base#base, n)////// Returns the logical right shift of `x` by `distance`./// Only the rightmost 6 bits of `distance` are considered (ie. `distance rem 64`)./// A zero is shifted into the leftmost position regardless of sign extension.///pubdeflogicalRightShift(dist: {dist = Int32}, x: Int64): Int64 =if (x<0i64andInt32.remainder(dist#dist, size()) !=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: Int64): Int32 = {if (x==0i64)0elseif (x`remainder`2i64!=0i64)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: Int64): Int64 =bitwiseOr(logicalRightShift(dist = dist#dist, x), leftShift(x, -dist#dist))////// Returns the value obtained by rotating the two's complement/// binary representation of `x` left by `distance` bits.///pubdefrotateLeft(dist: {dist = Int32}, x: Int64): Int64 =bitwiseOr(logicalRightShift(dist = -dist#dist, x), leftShift(x, dist#dist))////// Returns the value obtained by reversing the bits in the/// two's complement binary representation of `x`.///pubdefreverse(x: Int64): Int64 = reverseHelper(x, 0, size()-1)////// Helper function for `reverse`.///defreverseHelper(x: Int64, l: Int32, r: Int32): Int64 =if (l>=r) xelsereverseHelper(swap(x, l, r), l+1, r-1)////// Helper function for `reverse`.///defswap(x: Int64, l: Int32, r: Int32): Int64 = 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) - 63 (leftmost bit)/// -1 if x = 0///pubdefhighestOneBitPosition(x: Int64): Int32 =// Start at bit 63 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) - 63 (leftmost bit)/// -1 if x = 0///pubdeflowestOneBitPosition(x: Int64): 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: Int64, 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: Int64): Int64 =bitPositionToInt64(highestOneBitPosition(x))////// Returns a value with at most a single one-bit, in the position/// of the lowest-order/rightmost one-bit in `x`./// Returns 0 if x=0.///pubdeflowestOneBit(x: Int64): Int64 =bitPositionToInt64(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-63 inclusive.///defbitPositionToInt64(position: Int32): Int64 =if (position<0orposition>size()-1) 0i64elseleftShift(1i64, position)////// Returns the number of zero bits preceding the/// highest-order/leftmost one-bit in `x`./// Returns 64 if x=0.///pubdefnumberOfLeadingZeros(x: Int64): Int32 =if (x==0i64) size()elsesize()-1-highestOneBitPosition(x)////// Returns the number of zero bits following the/// lowest-order/rightmost one-bit in `x`./// Returns 64 if x=0.///pubdefnumberOfTrailingZeros(x: Int64): Int32 =if (x==0i64) size()elselowestOneBitPosition(x)////// Returns the bit of `x` at `position` (either 0 or 1)./// Considers the 6 rightmost bits of `position` (`position` modulo 64)./// The bits of x have positions: 0 (rightmost bit) - 63 (leftmost bit).///pubdefgetBit(pos: {pos = Int32}, x: Int64): Int32 =if (rightShift(x, pos#pos) `remainder`2i64==0i64) 0else1////// Returns `x` with the bit at position `position` set (to 1)./// Considers the 6 rightmost bits of `position` (`position` modulo 64)./// The bits of x have positions: 0 (rightmost bit) - 63 (leftmost bit)///pubdefsetBit(pos: {pos = Int32}, x: Int64): Int64 = bitwiseOr(x, leftShift(1i64, pos#pos))////// Returns `x` with the bit at position `position` cleared (to 0)./// Considers the 6 rightmost bits of `position` (`position` modulo 64)./// The bits of x have positions: 0 (rightmost bit) - 63 (leftmost bit)///pubdefclearBit(pos: {pos = Int32}, x: Int64): Int64 = bitwiseAnd(x, bitwiseNot(leftShift(1i64, pos#pos)))////// Returns `x` with the bit at position `position` flipped./// Considers the 6 rightmost bits of `position` (`position` modulo 64)./// The bits of x have positions: 0 (rightmost bit) - 63 (leftmost bit)///pubdefflipBit(pos: {pos = Int32}, x: Int64): Int64 = bitwiseXor(x, leftShift(1i64, pos#pos))////// Returns the integer binary logarithm of `x`./// If the given value is 0 or negative, 0 is returned.///pubdeflog2(x: Int64): Int64 =if (x<=0i64) {0i64 } else {highestOneBitPosition(x) |> Int32.toInt64 }////// Returns `x` with the bits shifted left by `y` places///pubdefleftShift(x: Int64, y: Int32): Int64 = %%INT64_SHL%%(x, y)////// Returns `x` with the bits shifted right by `y` places///pubdefrightShift(x: Int64, y: Int32): Int64 = %%INT64_SHR%%(x, y)////// Returns the bitwise AND of `x` and `y`.///pubdefbitwiseAnd(x: Int64, y: Int64): Int64 = %%INT64_AND%%(x, y)////// Returns the bitwise NOT of `x`.///pubdefbitwiseNot(x: Int64): Int64 = %%INT64_NOT%%(x)////// Returns the bitwise OR of `x` and `y`.///pubdefbitwiseOr(x: Int64, y: Int64): Int64 = %%INT64_OR%%(x, y)////// Returns the bitwise XOR of `x` and `y`.///pubdefbitwiseXor(x: Int64, y: Int64): Int64 = %%INT64_XOR%%(x, y)////// Returns the factorial of `x`./// If the given value is negative, 0 is returned.///pubdeffactorial(x: Int64): Int64 =if (x<0i64) {0i64 } else {defloop(y, acc) = matchy {case 0i64 => acccase_ => loop(y-1i64, y*acc) };loop(x, 1i64) }////// Return a string representation of `x`.///pubdeftoString(x: Int64): String = ToString.toString(x)////// Parse the string `s` as an Int64, 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[Int64] = try { Some(Long.parseLong(s.strip())) } catch {case_: NumberFormatException => None }////// Parse the string `s` as an Int64, where the `radix` is used while parsing./// Leading or trailing whitespace is trimmed./// A successful parse is wrapped with `Ok(x)`, a parse failure is indicated by `Err(_)`.///pubdefparse(radix: Int32, s: String): Result[String, Int64] = try { Ok(Long.parseLong(s.strip(), radix)) } catch {case_: NumberFormatException => Err("Int64.parse") }////// 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: Int64): Option[Int8] =if (x<Int8.toInt64(Int8.minValue()) orx>Int8.toInt64(Int8.maxValue())) Noneelse Some(Long.valueOf(x).byteValue())////// Convert `x` to an `Option[Int16]`.////// Returns `Some(x as Int16)` if the numeric value of `x` can be represented exactly.////// Returns `None` if the numeric value of `x` is outside the range of Int16/// (i.e. -32768 to 32767).///pubdeftryToInt16(x: Int64): Option[Int16] =if (x<Int16.toInt64(Int16.minValue()) orx>Int16.toInt64(Int16.maxValue())) Noneelse Some(Long.valueOf(x).shortValue())////// Convert `x` to an `Option[Int32]`.////// Returns `Some(x as Int32)` if the numeric value of `x` can be represented exactly.////// Returns `None` if the numeric value of `x` is outside the range of Int32/// (i.e. -2147483648 to 2147483647).///pubdeftryToInt32(x: Int64): Option[Int32] =if (x<Int32.toInt64(Int32.minValue()) orx>Int32.toInt64(Int32.maxValue())) Noneelse Some(Long.valueOf(x).intValue())////// Convert `x` to a BigInt.////// The numeric value of `x` is preserved exactly.///pubdeftoBigInt(x: Int64): BigInt = BigInteger.valueOf(Long.valueOf(x).longValue())////// Convert `x` to a Float32.////// Warning: The numeric value of `x` may lose precision.///pubdeftoFloat32(x: Int64): Float32 = Long.valueOf(x).floatValue()////// Convert `x` to a Float64.////// Warning: The numeric value of `x` may lose precision.///pubdeftoFloat64(x: Int64): Float64 = Long.valueOf(x).doubleValue()////// Convert `x` to a BigDecimal.////// Warning: The numeric value of `x` may lose precision.///pubdeftoBigDecimal(x: Int64): BigDecimal =new BigDecimal(x)////// Helper function for the `clamp` conversion functions.///defclamp(min: {min = Int64}, max: {max = Int64}, x: Int64): Int64 =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: Int64): Int8 =letmini64 = Int8.toInt64(min#min);letmaxi64 = Int8.toInt64(max#max); Long.valueOf(clamp(min = mini64, max = maxi64, x)).byteValue()////// Convert `x` to an `Int16`.////// Returns `x` clamped within the Int16 range `min` to `max`.///pubdefclampToInt16(min: {min = Int16}, max: {max = Int16}, x: Int64): Int16 =letmini64 = Int16.toInt64(min#min);letmaxi64 = Int16.toInt64(max#max); Long.valueOf(clamp(min = mini64, max = maxi64, x)).shortValue()////// Convert `x` to an `Int32`.////// Returns `x` clamped within the Int32 range `min` to `max`.///pubdefclampToInt32(min: {min = Int32}, max: {max = Int32}, x: Int64): Int32 =letmini64 = Int32.toInt64(min#min);letmaxi64 = Int32.toInt64(max#max); Long.valueOf(clamp(min = mini64, max = maxi64, x)).intValue()////// Convert `x` to an Int32 by truncation.////// Discards all but the lowest 32 bits.///pubdeftruncateToInt32(x: Int64): Int32 = Long.valueOf(x).intValue()////// Get the primitive Int64 value from its object representation (i.e. Long).////// This function is expected to be used when marshaling Int64s from Java. Generally in Flix/// code you should not need to use `Long`.///pubdeflongValue(i: Long): Int64 =i.longValue()////// Convert an Int64 value to its object representation (i.e. Long).////// This function is expected to be used when marshaling Int64s to Java. Generally in Flix/// code you should not need to use `Long`.///pubdefvalueOf(i: Int64): Long = Long.valueOf(i)}