From 452b7db793499b2c08dedd5337bc96cdef187779 Mon Sep 17 00:00:00 2001 From: Kento Sugama <107421898+kentosugama@users.noreply.github.com> Date: Mon, 21 Aug 2023 11:58:36 -0400 Subject: [PATCH] Bindings for adjacent fix-width numerical conversions and flesh out docs (#585) Expose these new primitives to convert between adjacent fix-width types: - `Int8` - `Int16` - `Int32` - `Int64` - `Nat8` - `Nat16` - `Nat32` - `Nat64` And fleshing out the documentation for these modules to be up to standard with the `Nat` and `Int` modules. --- src/Int.mo | 5 + src/Int16.mo | 414 ++++++++++++++++++++++++++++---------------- src/Int32.mo | 427 +++++++++++++++++++++++++++++---------------- src/Int64.mo | 415 ++++++++++++++++++++++++++++---------------- src/Int8.mo | 414 ++++++++++++++++++++++++++++---------------- src/Nat16.mo | 471 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/Nat32.mo | 476 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/Nat64.mo | 457 +++++++++++++++++++++++++++++++++++++++++++++++-- src/Nat8.mo | 453 ++++++++++++++++++++++++++++++++++++++++++++++-- 9 files changed, 2864 insertions(+), 668 deletions(-) diff --git a/src/Int.mo b/src/Int.mo index d2b41db6..0dd479cb 100644 --- a/src/Int.mo +++ b/src/Int.mo @@ -249,6 +249,11 @@ module { /// ```motoko include=import /// Int.neg(123) // => -123 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. public func neg(x : Int) : Int { -x }; /// Returns the sum of `x` and `y`, `x + y`. diff --git a/src/Int16.mo b/src/Int16.mo index a0c7183f..aa83787d 100644 --- a/src/Int16.mo +++ b/src/Int16.mo @@ -1,7 +1,11 @@ -/// 16-bit signed integers with checked arithmetic. +/// Provides utility functions on 16-bit signed integers. /// -/// Common 16-bit integer functions. -/// Most operations are available as built-in operators (e.g. `1 + 1`). +/// Note that most operations are available as built-in operators (e.g. `1 + 1`). +/// +/// Import from the base library to use this module. +/// ```motoko name=import +/// import Int16 "mo:base/Int16"; +/// ``` import Int "Int"; import Prim "mo:⛔"; @@ -11,17 +15,25 @@ module { public type Int16 = Prim.Types.Int16; /// Minimum 16-bit integer value, `-2 ** 15`. + /// + /// Example: + /// ```motoko include=import + /// Int16.minimumValue // => -32_768 : Int16 + /// ``` public let minimumValue = -32_768 : Int16; /// Maximum 16-bit integer value, `+2 ** 15 - 1`. + /// + /// Example: + /// ```motoko include=import + /// Int16.maximumValue // => +32_767 : Int16 + /// ``` public let maximumValue = 32_767 : Int16; /// Converts a 16-bit signed integer to a signed integer with infinite precision. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.toInt(12_345) // => 12_345 : Int /// ``` public let toInt : Int16 -> Int = Prim.int16ToInt; @@ -31,9 +43,7 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.fromInt(12_345) // => +12_345 : Int16 /// ``` public let fromInt : Int -> Int16 = Prim.intToInt16; @@ -43,21 +53,53 @@ module { /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.fromIntWrap(-12_345) // => -12_345 : Int /// ``` public let fromIntWrap : Int -> Int16 = Prim.intToInt16Wrap; + /// Converts a 8-bit signed integer to a 16-bit signed integer. + /// + /// Example: + /// ```motoko include=import + /// Int16.fromInt8(-123) // => -123 : Int16 + /// ``` + public let fromInt8 : Int8 -> Int16 = Prim.int8ToInt16; + + /// Converts a 16-bit signed integer to a 8-bit signed integer. + /// + /// Traps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Int16.toInt8(-123) // => -123 : Int8 + /// ``` + public let toInt8 : Int16 -> Int8 = Prim.int16ToInt8; + + /// Converts a 32-bit signed integer to a 16-bit signed integer. + /// + /// Traps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Int16.fromInt32(-12_345) // => -12_345 : Int16 + /// ``` + public let fromInt32 : Int32 -> Int16 = Prim.int32ToInt16; + + /// Converts a 16-bit signed integer to a 32-bit signed integer. + /// + /// Example: + /// ```motoko include=import + /// Int16.toInt32(-12_345) // => -12_345 : Int32 + /// ``` + public let toInt32 : Int16 -> Int32 = Prim.int16ToInt32; + /// Converts an unsigned 16-bit integer to a signed 16-bit integer. /// /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.fromNat16(12_345) // => +12_345 : Int16 /// ``` public let fromNat16 : Nat16 -> Int16 = Prim.nat16ToInt16; @@ -67,20 +109,16 @@ module { /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.toNat16(-1) // => 65_535 : Nat16 // underflow /// ``` public let toNat16 : Int16 -> Nat16 = Prim.int16ToNat16; - /// Returns the Text representation of `x`. - /// Formats the integer in decimal representation without underscore separators for thousand figures. + /// Returns the Text representation of `x`. Textual representation _do not_ + /// contain underscores to represent commas. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.toText(-12345) // => "-12345" /// ``` public func toText(x : Int16) : Text { @@ -92,9 +130,7 @@ module { /// Traps when `x == -2 ** 15` (the minimum `Int16` value). /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.abs(-12345) // => +12_345 /// ``` public func abs(x : Int16) : Int16 { @@ -104,9 +140,7 @@ module { /// Returns the minimum of `x` and `y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.min(+2, -3) // => -3 /// ``` public func min(x : Int16, y : Int16) : Int16 { @@ -116,82 +150,112 @@ module { /// Returns the maximum of `x` and `y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.max(+2, -3) // => +2 /// ``` public func max(x : Int16, y : Int16) : Int16 { if (x < y) { y } else { x } }; - /// Returns `x == y`. + /// Equality function for Int16 types. + /// This is equivalent to `x == y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; + /// ```motoko include=import + /// Int16.equal(-1, -1); // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `==` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `==` + /// as a function value at the moment. /// - /// Int16.equal(123, 123) // => true + /// Example: + /// ```motoko include=import + /// import Buffer "mo:base/Buffer"; + /// + /// let buffer1 = Buffer.Buffer(1); + /// buffer1.add(-3); + /// let buffer2 = Buffer.Buffer(1); + /// buffer2.add(-3); + /// Buffer.equal(buffer1, buffer2, Int16.equal) // => true /// ``` public func equal(x : Int16, y : Int16) : Bool { x == y }; - /// Returns `x != y`. + /// Inequality function for Int16 types. + /// This is equivalent to `x != y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// - /// Int16.notEqual(123, 123) // => false + /// ```motoko include=import + /// Int16.notEqual(-1, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `!=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `!=` + /// as a function value at the moment. public func notEqual(x : Int16, y : Int16) : Bool { x != y }; - /// Returns `x < y`. + /// "Less than" function for Int16 types. + /// This is equivalent to `x < y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// - /// Int16.less(123, 1234) // => true + /// ```motoko include=import + /// Int16.less(-2, 1); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<` + /// as a function value at the moment. public func less(x : Int16, y : Int16) : Bool { x < y }; - /// Returns `x <= y`. + /// "Less than or equal" function for Int16 types. + /// This is equivalent to `x <= y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// - /// Int16.lessOrEqual(123, 1234) // => true + /// ```motoko include=import + /// Int16.lessOrEqual(-2, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<=` + /// as a function value at the moment. public func lessOrEqual(x : Int16, y : Int16) : Bool { x <= y }; - /// Returns `x > y`. + /// "Greater than" function for Int16 types. + /// This is equivalent to `x > y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// - /// Int16.greater(1234, 123) // => true + /// ```motoko include=import + /// Int16.greater(-2, 1); // => false /// ``` public func greater(x : Int16, y : Int16) : Bool { x > y }; - /// Returns `x >= y`. + /// "Greater than or equal" function for Int16 types. + /// This is equivalent to `x >= y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// - /// Int16.greaterOrEqual(1234, 123) // => true + /// ```motoko include=import + /// Int16.greaterOrEqual(-2, -2); // => true /// ``` public func greaterOrEqual(x : Int16, y : Int16) : Bool { x >= y }; - /// Returns the order of `x` and `y`. + /// General-purpose comparison function for `Int16`. Returns the `Order` ( + /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; + /// ```motoko include=import + /// Int16.compare(-3, 2) // => #less + /// ``` + /// + /// This function can be used as value for a high order function, such as a sort function. /// - /// Int16.compare(123, 1234) // => #less + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.sort([1, -2, -3] : [Int16], Int16.compare) // => [-3, -2, 1] /// ``` public func compare(x : Int16, y : Int16) : { #less; #equal; #greater } { if (x < y) { #less } else if (x == y) { #equal } else { #greater } @@ -201,13 +265,15 @@ module { /// /// Traps on overflow, i.e. for `neg(-2 ** 15)`. /// - /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.neg(123) // => -123 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. public func neg(x : Int16) : Int16 { -x }; /// Returns the sum of `x` and `y`, `x + y`. @@ -215,10 +281,19 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; + /// ```motoko include=import + /// Int16.add(100, 23) // => +123 + /// ``` /// - /// Int16.add(1234, 123) // => +1_357 + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 0, Int16.add) // => -4 /// ``` public func add(x : Int16, y : Int16) : Int16 { x + y }; @@ -227,10 +302,19 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; + /// ```motoko include=import + /// Int16.sub(123, 100) // => +23 + /// ``` /// - /// Int16.sub(1234, 123) // => +1_111 + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 0, Int16.sub) // => 4 /// ``` public func sub(x : Int16, y : Int16) : Int16 { x - y }; @@ -239,10 +323,19 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; + /// ```motoko include=import + /// Int16.mul(12, 10) // => +120 + /// ``` /// - /// Int16.mul(123, 100) // => +12_300 + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 1, Int16.mul) // => 6 /// ``` public func mul(x : Int16, y : Int16) : Int16 { x * y }; @@ -252,11 +345,14 @@ module { /// Traps when `y` is zero. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.div(123, 10) // => +12 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `/` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `/` + /// as a function value at the moment. public func div(x : Int16, y : Int16) : Int16 { x / y }; /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`, @@ -265,11 +361,14 @@ module { /// Traps when `y` is zero. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.rem(123, 10) // => +3 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `%` + /// as a function value at the moment. public func rem(x : Int16, y : Int16) : Int16 { x % y }; /// Returns `x` to the power of `y`, `x ** y`. @@ -277,51 +376,64 @@ module { /// Traps on overflow/underflow and when `y < 0 or y >= 16`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.pow(2, 10) // => +1_024 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**` + /// as a function value at the moment. public func pow(x : Int16, y : Int16) : Int16 { x ** y }; /// Returns the bitwise negation of `x`, `^x`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitnot(-256 /* 0xff00 */) // => +255 // 0xff /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitnot(x : Int16) : Int16 { ^x }; /// Returns the bitwise "and" of `x` and `y`, `x & y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitand(0x0fff, 0x00f0) // => +240 // 0xf0 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `&` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `&` + /// as a function value at the moment. public func bitand(x : Int16, y : Int16) : Int16 { x & y }; /// Returns the bitwise "or" of `x` and `y`, `x | y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitor(0x0f0f, 0x00f0) // => +4_095 // 0x0fff /// ``` + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `|` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `|` + /// as a function value at the moment. public func bitor(x : Int16, y : Int16) : Int16 { x | y }; /// Returns the bitwise "exclusive or" of `x` and `y`, `x ^ y`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitxor(0x0fff, 0x00f0) // => +3_855 // 0x0f0f /// ``` + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitxor(x : Int16, y : Int16) : Int16 { x ^ y }; /// Returns the bitwise left shift of `x` by `y`, `x << y`. @@ -332,11 +444,14 @@ module { /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 16)`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<` + /// as a function value at the moment. public func bitshiftLeft(x : Int16, y : Int16) : Int16 { x << y }; /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`. @@ -347,11 +462,14 @@ module { /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 16)`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)` /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>>` + /// as a function value at the moment. public func bitshiftRight(x : Int16, y : Int16) : Int16 { x >> y }; /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`. @@ -362,11 +480,14 @@ module { /// For `y >= 16`, the semantics is the same as for `bitrotLeft(x, y % 16)`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitrotLeft(0x2001, 4) // => +18 // 0x12. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<>` + /// as a function value at the moment. public func bitrotLeft(x : Int16, y : Int16) : Int16 { x <<> y }; /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`. @@ -377,20 +498,22 @@ module { /// For `y >= 16`, the semantics is the same as for `bitrotRight(x, y % 16)`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitrotRight(0x2010, 8) // => +4_128 // 0x01020. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<>>` + /// as a function value at the moment. public func bitrotRight(x : Int16, y : Int16) : Int16 { x <>> y }; /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`. /// If `p >= 16`, the semantics is the same as for `bittest(x, p % 16)`. + /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bittest(128, 7) // => true /// ``` public func bittest(x : Int16, p : Nat) : Bool { @@ -401,9 +524,7 @@ module { /// If `p >= 16`, the semantics is the same as for `bitset(x, p % 16)`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitset(0, 7) // => +128 /// ``` public func bitset(x : Int16, p : Nat) : Int16 { @@ -414,9 +535,7 @@ module { /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitclear(-1, 7) // => -129 /// ``` public func bitclear(x : Int16, p : Nat) : Int16 { @@ -427,9 +546,7 @@ module { /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitflip(255, 7) // => +127 /// ``` public func bitflip(x : Int16, p : Nat) : Int16 { @@ -439,9 +556,7 @@ module { /// Returns the count of non-zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitcountNonZero(0xff) // => +8 /// ``` public let bitcountNonZero : (x : Int16) -> Int16 = Prim.popcntInt16; @@ -449,9 +564,7 @@ module { /// Returns the count of leading zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitcountLeadingZero(0x80) // => +8 /// ``` public let bitcountLeadingZero : (x : Int16) -> Int16 = Prim.clzInt16; @@ -459,9 +572,7 @@ module { /// Returns the count of trailing zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.bitcountTrailingZero(0x0100) // => +8 /// ``` public let bitcountTrailingZero : (x : Int16) -> Int16 = Prim.ctzInt16; @@ -470,39 +581,45 @@ module { /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.addWrap(2 ** 14, 2 ** 14) // => -32_768 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+%` + /// as a function value at the moment. public func addWrap(x : Int16, y : Int16) : Int16 { x +% y }; /// Returns the difference of `x` and `y`, `x -% y`. /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.subWrap(-2 ** 15, 1) // => +32_767 // underflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-%` + /// as a function value at the moment. public func subWrap(x : Int16, y : Int16) : Int16 { x -% y }; /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow. /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; - /// + /// ```motoko include=import /// Int16.mulWrap(2 ** 8, 2 ** 8) // => 0 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*%` + /// as a function value at the moment. public func mulWrap(x : Int16, y : Int16) : Int16 { x *% y }; /// Returns `x` to the power of `y`, `x **% y`. @@ -510,12 +627,15 @@ module { /// Wraps on overflow/underflow. /// Traps if `y < 0 or y >= 16`. /// - /// /// Example: - /// ```motoko - /// import Int16 "mo:base/Int16"; + /// ```motoko include=import /// /// Int16.powWrap(2, 15) // => -32_768 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**%` + /// as a function value at the moment. public func powWrap(x : Int16, y : Int16) : Int16 { x **% y } } diff --git a/src/Int32.mo b/src/Int32.mo index aa634fd7..30f06617 100644 --- a/src/Int32.mo +++ b/src/Int32.mo @@ -1,7 +1,11 @@ -/// 32-bit signed integers with checked arithmetic. +/// Provides utility functions on 32-bit signed integers. /// -/// Common 32-bit integer functions. -/// Most operations are available as built-in operators (e.g. `1 + 1`). +/// Note that most operations are available as built-in operators (e.g. `1 + 1`). +/// +/// Import from the base library to use this module. +/// ```motoko name=import +/// import Int32 "mo:base/Int32"; +/// ``` import Int "Int"; import Prim "mo:⛔"; @@ -11,17 +15,25 @@ module { public type Int32 = Prim.Types.Int32; /// Minimum 32-bit integer value, `-2 ** 31`. + /// + /// Example: + /// ```motoko include=import + /// Int32.minimumValue // => -2_147_483_648 + /// ``` public let minimumValue = -2_147_483_648 : Int32; /// Maximum 32-bit integer value, `+2 ** 31 - 1`. + /// + /// Example: + /// ```motoko include=import + /// Int32.maximumValue // => +2_147_483_647 + /// ``` public let maximumValue = 2_147_483_647 : Int32; /// Converts a 32-bit signed integer to a signed integer with infinite precision. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.toInt(123_456) // => 123_456 : Int /// ``` public let toInt : Int32 -> Int = Prim.int32ToInt; @@ -31,9 +43,7 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.fromInt(123_456) // => +123_456 : Int32 /// ``` public let fromInt : Int -> Int32 = Prim.intToInt32; @@ -43,21 +53,53 @@ module { /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.fromIntWrap(-123_456) // => -123_456 : Int /// ``` public let fromIntWrap : Int -> Int32 = Prim.intToInt32Wrap; + /// Converts a 16-bit signed integer to a 32-bit signed integer. + /// + /// Example: + /// ```motoko include=import + /// Int32.fromInt16(-123) // => -123 : Int32 + /// ``` + public let fromInt16 : Int16 -> Int32 = Prim.int16ToInt32; + + /// Converts a 32-bit signed integer to a 16-bit signed integer. + /// + /// Traps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Int32.toInt16(-123) // => -123 : Int16 + /// ``` + public let toInt16 : Int32 -> Int16 = Prim.int32ToInt16; + + /// Converts a 64-bit signed integer to a 32-bit signed integer. + /// + /// Traps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Int32.fromInt64(-123_456) // => -123_456 : Int32 + /// ``` + public let fromInt64 : Int64 -> Int32 = Prim.int64ToInt32; + + /// Converts a 32-bit signed integer to a 64-bit signed integer. + /// + /// Example: + /// ```motoko include=import + /// Int32.toInt64(-123_456) // => -123_456 : Int64 + /// ``` + public let toInt64 : Int32 -> Int64 = Prim.int32ToInt64; + /// Converts an unsigned 32-bit integer to a signed 32-bit integer. /// /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.fromNat32(123_456) // => +123_456 : Int32 /// ``` public let fromNat32 : Nat32 -> Int32 = Prim.nat32ToInt32; @@ -67,20 +109,16 @@ module { /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.toNat32(-1) // => 4_294_967_295 : Nat32 // underflow /// ``` public let toNat32 : Int32 -> Nat32 = Prim.int32ToNat32; - /// Returns the Text representation of `x`. - /// Formats the integer in decimal representation without underscore separators for thousand figures. + /// Returns the Text representation of `x`. Textual representation _do not_ + /// contain underscores to represent commas. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.toText(-123456) // => "-123456" /// ``` public func toText(x : Int32) : Text { @@ -92,9 +130,7 @@ module { /// Traps when `x == -2 ** 31` (the minimum `Int32` value). /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.abs(-123456) // => +123_456 /// ``` public func abs(x : Int32) : Int32 { @@ -104,9 +140,7 @@ module { /// Returns the minimum of `x` and `y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.min(+2, -3) // => -3 /// ``` public func min(x : Int32, y : Int32) : Int32 { @@ -116,82 +150,122 @@ module { /// Returns the maximum of `x` and `y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.max(+2, -3) // => +2 /// ``` public func max(x : Int32, y : Int32) : Int32 { if (x < y) { y } else { x } }; - /// Returns `x == y`. + /// Equality function for Int32 types. + /// This is equivalent to `x == y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; + /// ```motoko include=import + /// Int32.equal(-1, -1); // => true + /// ``` /// - /// Int32.equal(123, 123) // => true + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `==` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `==` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Buffer "mo:base/Buffer"; + /// + /// let buffer1 = Buffer.Buffer(1); + /// buffer1.add(-3); + /// let buffer2 = Buffer.Buffer(1); + /// buffer2.add(-3); + /// Buffer.equal(buffer1, buffer2, Int32.equal) // => true /// ``` public func equal(x : Int32, y : Int32) : Bool { x == y }; - /// Returns `x != y`. + /// Inequality function for Int32 types. + /// This is equivalent to `x != y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// - /// Int32.notEqual(123, 123) // => false + /// ```motoko include=import + /// Int32.notEqual(-1, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `!=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `!=` + /// as a function value at the moment. public func notEqual(x : Int32, y : Int32) : Bool { x != y }; - /// Returns `x < y`. + /// "Less than" function for Int32 types. + /// This is equivalent to `x < y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// - /// Int32.less(123, 1234) // => true + /// ```motoko include=import + /// Int32.less(-2, 1); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<` + /// as a function value at the moment. public func less(x : Int32, y : Int32) : Bool { x < y }; - /// Returns `x <= y`. + /// "Less than or equal" function for Int32 types. + /// This is equivalent to `x <= y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// - /// Int32.lessOrEqual(123, 1234) // => true + /// ```motoko include=import + /// Int32.lessOrEqual(-2, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<=` + /// as a function value at the moment. public func lessOrEqual(x : Int32, y : Int32) : Bool { x <= y }; - /// Returns `x > y`. + /// "Greater than" function for Int32 types. + /// This is equivalent to `x > y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// - /// Int32.greater(1234, 123) // => true + /// ```motoko include=import + /// Int32.greater(-2, -3); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>` + /// as a function value at the moment. public func greater(x : Int32, y : Int32) : Bool { x > y }; - /// Returns `x >= y`. + /// "Greater than or equal" function for Int32 types. + /// This is equivalent to `x >= y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// - /// Int32.greaterOrEqual(1234, 123) // => true + /// ```motoko include=import + /// Int32.greaterOrEqual(-2, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>=` + /// as a function value at the moment. public func greaterOrEqual(x : Int32, y : Int32) : Bool { x >= y }; - /// Returns the order of `x` and `y`. + /// General-purpose comparison function for `Int32`. Returns the `Order` ( + /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; + /// ```motoko include=import + /// Int32.compare(-3, 2) // => #less + /// ``` + /// + /// This function can be used as value for a high order function, such as a sort function. /// - /// Int32.compare(123, 1234) // => #less + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.sort([1, -2, -3] : [Int32], Int32.compare) // => [-3, -2, 1] /// ``` public func compare(x : Int32, y : Int32) : { #less; #equal; #greater } { if (x < y) { #less } else if (x == y) { #equal } else { #greater } @@ -201,13 +275,15 @@ module { /// /// Traps on overflow, i.e. for `neg(-2 ** 31)`. /// - /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.neg(123) // => -123 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. public func neg(x : Int32) : Int32 { -x }; /// Returns the sum of `x` and `y`, `x + y`. @@ -215,10 +291,19 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; + /// ```motoko include=import + /// Int32.add(100, 23) // => +123 + /// ``` /// - /// Int32.add(1234, 123) // => +1_357 + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 0, Int32.add) // => -4 /// ``` public func add(x : Int32, y : Int32) : Int32 { x + y }; @@ -227,11 +312,20 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.sub(1234, 123) // => +1_111 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 0, Int32.sub) // => 6 + /// ``` public func sub(x : Int32, y : Int32) : Int32 { x - y }; /// Returns the product of `x` and `y`, `x * y`. @@ -239,11 +333,20 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.mul(123, 100) // => +12_300 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 1, Int32.mul) // => 6 + /// ``` public func mul(x : Int32, y : Int32) : Int32 { x * y }; /// Returns the signed integer division of `x` by `y`, `x / y`. @@ -252,11 +355,14 @@ module { /// Traps when `y` is zero. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.div(123, 10) // => +12 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `/` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `/` + /// as a function value at the moment. public func div(x : Int32, y : Int32) : Int32 { x / y }; /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`, @@ -265,11 +371,14 @@ module { /// Traps when `y` is zero. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.rem(123, 10) // => +3 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `%` + /// as a function value at the moment. public func rem(x : Int32, y : Int32) : Int32 { x % y }; /// Returns `x` to the power of `y`, `x ** y`. @@ -277,51 +386,66 @@ module { /// Traps on overflow/underflow and when `y < 0 or y >= 32`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.pow(2, 10) // => +1_024 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**` + /// as a function value at the moment. public func pow(x : Int32, y : Int32) : Int32 { x ** y }; /// Returns the bitwise negation of `x`, `^x`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitnot(-256 /* 0xffff_ff00 */) // => +255 // 0xff /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitnot(x : Int32) : Int32 { ^x }; /// Returns the bitwise "and" of `x` and `y`, `x & y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitand(0xffff, 0x00f0) // => +240 // 0xf0 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `&` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `&` + /// as a function value at the moment. public func bitand(x : Int32, y : Int32) : Int32 { x & y }; /// Returns the bitwise "or" of `x` and `y`, `x | y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitor(0xffff, 0x00f0) // => +65_535 // 0xffff /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `|` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `|` + /// as a function value at the moment. public func bitor(x : Int32, y : Int32) : Int32 { x | y }; /// Returns the bitwise "exclusive or" of `x` and `y`, `x ^ y`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitxor(0xffff, 0x00f0) // => +65_295 // 0xff0f /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitxor(x : Int32, y : Int32) : Int32 { x ^ y }; /// Returns the bitwise left shift of `x` by `y`, `x << y`. @@ -332,11 +456,14 @@ module { /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 32)`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<` + /// as a function value at the moment. public func bitshiftLeft(x : Int32, y : Int32) : Int32 { x << y }; /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`. @@ -347,11 +474,14 @@ module { /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 32)`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)` /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>>` + /// as a function value at the moment. public func bitshiftRight(x : Int32, y : Int32) : Int32 { x >> y }; /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`. @@ -362,11 +492,14 @@ module { /// For `y >= 32`, the semantics is the same as for `bitrotLeft(x, y % 32)`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitrotLeft(0x2000_0001, 4) // => +18 // 0x12. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<>` + /// as a function value at the moment. public func bitrotLeft(x : Int32, y : Int32) : Int32 { x <<> y }; /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`. @@ -377,20 +510,22 @@ module { /// For `y >= 32`, the semantics is the same as for `bitrotRight(x, y % 32)`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitrotRight(0x0002_0001, 8) // => +16_777_728 // 0x0100_0200. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<>>` + /// as a function value at the moment. public func bitrotRight(x : Int32, y : Int32) : Int32 { x <>> y }; /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`. /// If `p >= 32`, the semantics is the same as for `bittest(x, p % 32)`. + /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bittest(128, 7) // => true /// ``` public func bittest(x : Int32, p : Nat) : Bool { @@ -401,9 +536,7 @@ module { /// If `p >= 32`, the semantics is the same as for `bitset(x, p % 32)`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitset(0, 7) // => +128 /// ``` public func bitset(x : Int32, p : Nat) : Int32 { @@ -414,9 +547,7 @@ module { /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitclear(-1, 7) // => -129 /// ``` public func bitclear(x : Int32, p : Nat) : Int32 { @@ -427,9 +558,7 @@ module { /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitflip(255, 7) // => +127 /// ``` public func bitflip(x : Int32, p : Nat) : Int32 { @@ -439,9 +568,7 @@ module { /// Returns the count of non-zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitcountNonZero(0xffff) // => +16 /// ``` public let bitcountNonZero : (x : Int32) -> Int32 = Prim.popcntInt32; @@ -449,9 +576,7 @@ module { /// Returns the count of leading zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitcountLeadingZero(0x8000) // => +16 /// ``` public let bitcountLeadingZero : (x : Int32) -> Int32 = Prim.clzInt32; @@ -459,9 +584,7 @@ module { /// Returns the count of trailing zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.bitcountTrailingZero(0x0201_0000) // => +16 /// ``` public let bitcountTrailingZero : (x : Int32) -> Int32 = Prim.ctzInt32; @@ -470,39 +593,45 @@ module { /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.addWrap(2 ** 30, 2 ** 30) // => -2_147_483_648 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+%` + /// as a function value at the moment. public func addWrap(x : Int32, y : Int32) : Int32 { x +% y }; /// Returns the difference of `x` and `y`, `x -% y`. /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.subWrap(-2 ** 31, 1) // => +2_147_483_647 // underflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-%` + /// as a function value at the moment. public func subWrap(x : Int32, y : Int32) : Int32 { x -% y }; /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow. /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.mulWrap(2 ** 16, 2 ** 16) // => 0 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*%` + /// as a function value at the moment. public func mulWrap(x : Int32, y : Int32) : Int32 { x *% y }; /// Returns `x` to the power of `y`, `x **% y`. @@ -510,13 +639,15 @@ module { /// Wraps on overflow/underflow. /// Traps if `y < 0 or y >= 32`. /// - /// /// Example: - /// ```motoko - /// import Int32 "mo:base/Int32"; - /// + /// ```motoko include=import /// Int32.powWrap(2, 31) // => -2_147_483_648 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**%` + /// as a function value at the moment. public func powWrap(x : Int32, y : Int32) : Int32 { x **% y }; } diff --git a/src/Int64.mo b/src/Int64.mo index 386fa957..171760eb 100644 --- a/src/Int64.mo +++ b/src/Int64.mo @@ -1,7 +1,12 @@ -/// 64-bit signed integers with checked arithmetic. +/// Provides utility functions on 64-bit signed integers. /// -/// Common 64-bit integer functions. -/// Most operations are available as built-in operators (e.g. `1 + 1`). +/// Note that most operations are available as built-in operators (e.g. `1 + 1`). +/// +/// Import from the base library to use this module. +/// ```motoko name=import +/// import Int64 "mo:base/Int64"; +/// ``` + import Int "Int"; import Prim "mo:⛔"; @@ -11,17 +16,25 @@ module { public type Int64 = Prim.Types.Int64; /// Minimum 64-bit integer value, `-2 ** 63`. + /// + /// Example: + /// ```motoko include=import + /// Int64.minimumValue // => -9_223_372_036_854_775_808 + /// ``` public let minimumValue = -9_223_372_036_854_775_808 : Int64; /// Maximum 64-bit integer value, `+2 ** 63 - 1`. + /// + /// Example: + /// ```motoko include=import + /// Int64.maximumValue // => +9_223_372_036_854_775_807 + /// ``` public let maximumValue = 9_223_372_036_854_775_807 : Int64; /// Converts a 64-bit signed integer to a signed integer with infinite precision. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.toInt(123_456) // => 123_456 : Int /// ``` public let toInt : Int64 -> Int = Prim.int64ToInt; @@ -31,21 +44,37 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.fromInt(123_456) // => +123_456 : Int64 /// ``` public let fromInt : Int -> Int64 = Prim.intToInt64; - /// Converts a signed integer with infinite precision to a 64-bit signed integer. + /// Converts a 32-bit signed integer to a 64-bit signed integer. + /// + /// Traps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Int64.fromInt32(-123_456) // => -123_456 : Int64 + /// ``` + public let fromInt32 : Int32 -> Int64 = Prim.int32ToInt64; + + /// Converts a 64-bit signed integer to a 32-bit signed integer. /// /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; + /// ```motoko include=import + /// Int64.toInt32(-123_456) // => -123_456 : Int32 + /// ``` + public let toInt32 : Int64 -> Int32 = Prim.int64ToInt32; + + /// Converts a signed integer with infinite precision to a 64-bit signed integer. /// + /// Wraps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import /// Int64.fromIntWrap(-123_456) // => -123_456 : Int64 /// ``` public let fromIntWrap : Int -> Int64 = Prim.intToInt64Wrap; @@ -55,9 +84,7 @@ module { /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.fromNat64(123_456) // => +123_456 : Int64 /// ``` public let fromNat64 : Nat64 -> Int64 = Prim.nat64ToInt64; @@ -67,20 +94,17 @@ module { /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.toNat64(-1) // => 18_446_744_073_709_551_615 : Nat64 // underflow /// ``` public let toNat64 : Int64 -> Nat64 = Prim.int64ToNat64; - /// Returns the Text representation of `x`. - /// Formats the integer in decimal representation without underscore separators for thousand figures. + /// Returns the Text representation of `x`. Textual representation _do not_ + /// contain underscores to represent commas. /// - /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; /// + /// Example: + /// ```motoko include=import /// Int64.toText(-123456) // => "-123456" /// ``` public func toText(x : Int64) : Text { @@ -92,9 +116,7 @@ module { /// Traps when `x == -2 ** 63` (the minimum `Int64` value). /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.abs(-123456) // => +123_456 /// ``` public func abs(x : Int64) : Int64 { @@ -104,9 +126,7 @@ module { /// Returns the minimum of `x` and `y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.min(+2, -3) // => -3 /// ``` public func min(x : Int64, y : Int64) : Int64 { @@ -116,82 +136,122 @@ module { /// Returns the maximum of `x` and `y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.max(+2, -3) // => +2 /// ``` public func max(x : Int64, y : Int64) : Int64 { if (x < y) { y } else { x } }; - /// Returns `x == y`. + /// Equality function for Int64 types. + /// This is equivalent to `x == y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; + /// ```motoko include=import + /// Int64.equal(-1, -1); // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `==` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `==` + /// as a function value at the moment. /// - /// Int64.equal(123, 123) // => true + /// Example: + /// ```motoko include=import + /// import Buffer "mo:base/Buffer"; + /// + /// let buffer1 = Buffer.Buffer(1); + /// buffer1.add(-3); + /// let buffer2 = Buffer.Buffer(1); + /// buffer2.add(-3); + /// Buffer.equal(buffer1, buffer2, Int64.equal) // => true /// ``` public func equal(x : Int64, y : Int64) : Bool { x == y }; - /// Returns `x != y`. + /// Inequality function for Int64 types. + /// This is equivalent to `x != y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// - /// Int64.notEqual(123, 123) // => false + /// ```motoko include=import + /// Int64.notEqual(-1, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `!=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `!=` + /// as a function value at the moment. public func notEqual(x : Int64, y : Int64) : Bool { x != y }; - /// Returns `x < y`. + /// "Less than" function for Int64 types. + /// This is equivalent to `x < y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// - /// Int64.less(123, 1234) // => true + /// ```motoko include=import + /// Int64.less(-2, 1); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<` + /// as a function value at the moment. public func less(x : Int64, y : Int64) : Bool { x < y }; - /// Returns `x <= y`. + /// "Less than or equal" function for Int64 types. + /// This is equivalent to `x <= y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// - /// Int64.lessOrEqual(123, 1234) // => true + /// ```motoko include=import + /// Int64.lessOrEqual(-2, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<=` + /// as a function value at the moment. public func lessOrEqual(x : Int64, y : Int64) : Bool { x <= y }; - /// Returns `x > y`. + /// "Greater than" function for Int64 types. + /// This is equivalent to `x > y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// - /// Int64.greater(1234, 123) // => true + /// ```motoko include=import + /// Int64.greater(-2, -3); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>` + /// as a function value at the moment. public func greater(x : Int64, y : Int64) : Bool { x > y }; - /// Returns `x >= y`. + /// "Greater than or equal" function for Int64 types. + /// This is equivalent to `x >= y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// - /// Int64.greaterOrEqual(1234, 123) // => true + /// ```motoko include=import + /// Int64.greaterOrEqual(-2, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>=` + /// as a function value at the moment. public func greaterOrEqual(x : Int64, y : Int64) : Bool { x >= y }; - /// Returns the order of `x` and `y`. + /// General-purpose comparison function for `Int64`. Returns the `Order` ( + /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; + /// ```motoko include=import + /// Int64.compare(-3, 2) // => #less + /// ``` /// - /// Int64.compare(123, 1234) // => #less + /// This function can be used as value for a high order function, such as a sort function. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.sort([1, -2, -3] : [Int64], Int64.compare) // => [-3, -2, 1] /// ``` public func compare(x : Int64, y : Int64) : { #less; #equal; #greater } { if (x < y) { #less } else if (x == y) { #equal } else { #greater } @@ -201,13 +261,15 @@ module { /// /// Traps on overflow, i.e. for `neg(-2 ** 63)`. /// - /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.neg(123) // => -123 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. public func neg(x : Int64) : Int64 { -x }; /// Returns the sum of `x` and `y`, `x + y`. @@ -215,11 +277,20 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.add(1234, 123) // => +1_357 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 0, Int64.add) // => -4 + /// ``` public func add(x : Int64, y : Int64) : Int64 { x + y }; /// Returns the difference of `x` and `y`, `x - y`. @@ -227,10 +298,19 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; + /// ```motoko include=import + /// Int64.sub(123, 100) // => +23 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. /// - /// Int64.sub(1234, 123) // => +1_111 + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 0, Int64.sub) // => 4 /// ``` public func sub(x : Int64, y : Int64) : Int64 { x - y }; @@ -239,10 +319,19 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; + /// ```motoko include=import + /// Int64.mul(123, 10) // => +1_230 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*` + /// as a function value at the moment. /// - /// Int64.mul(123, 100) // => +12_300 + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 1, Int64.mul) // => 6 /// ``` public func mul(x : Int64, y : Int64) : Int64 { x * y }; @@ -252,11 +341,14 @@ module { /// Traps when `y` is zero. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.div(123, 10) // => +12 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `/` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `/` + /// as a function value at the moment. public func div(x : Int64, y : Int64) : Int64 { x / y }; /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`, @@ -265,11 +357,14 @@ module { /// Traps when `y` is zero. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.rem(123, 10) // => +3 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `%` + /// as a function value at the moment. public func rem(x : Int64, y : Int64) : Int64 { x % y }; /// Returns `x` to the power of `y`, `x ** y`. @@ -277,51 +372,66 @@ module { /// Traps on overflow/underflow and when `y < 0 or y >= 64`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.pow(2, 10) // => +1_024 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**` + /// as a function value at the moment. public func pow(x : Int64, y : Int64) : Int64 { x ** y }; /// Returns the bitwise negation of `x`, `^x`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitnot(-256 /* 0xffff_ffff_ffff_ff00 */) // => +255 // 0xff /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitnot(x : Int64) : Int64 { ^x }; /// Returns the bitwise "and" of `x` and `y`, `x & y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitand(0xffff, 0x00f0) // => +240 // 0xf0 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `&` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `&` + /// as a function value at the moment. public func bitand(x : Int64, y : Int64) : Int64 { x & y }; /// Returns the bitwise "or" of `x` and `y`, `x | y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitor(0xffff, 0x00f0) // => +65_535 // 0xffff /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `|` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `|` + /// as a function value at the moment. public func bitor(x : Int64, y : Int64) : Int64 { x | y }; /// Returns the bitwise "exclusive or" of `x` and `y`, `x ^ y`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitxor(0xffff, 0x00f0) // => +65_295 // 0xff0f /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitxor(x : Int64, y : Int64) : Int64 { x ^ y }; /// Returns the bitwise left shift of `x` by `y`, `x << y`. @@ -332,11 +442,14 @@ module { /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 64)`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<` + /// as a function value at the moment. public func bitshiftLeft(x : Int64, y : Int64) : Int64 { x << y }; /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`. @@ -347,11 +460,14 @@ module { /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 64)`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)` /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>>` + /// as a function value at the moment. public func bitshiftRight(x : Int64, y : Int64) : Int64 { x >> y }; /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`. @@ -362,11 +478,15 @@ module { /// For `y >= 64`, the semantics is the same as for `bitrotLeft(x, y % 64)`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; + /// ```motoko include=import /// /// Int64.bitrotLeft(0x2000_0000_0000_0001, 4) // => +18 // 0x12. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<>` + /// as a function value at the moment. public func bitrotLeft(x : Int64, y : Int64) : Int64 { x <<> y }; /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`. @@ -377,20 +497,22 @@ module { /// For `y >= 64`, the semantics is the same as for `bitrotRight(x, y % 64)`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitrotRight(0x0002_0000_0000_0001, 48) // => +65538 // 0x1_0002. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<>>` + /// as a function value at the moment. public func bitrotRight(x : Int64, y : Int64) : Int64 { x <>> y }; /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`. /// If `p >= 64`, the semantics is the same as for `bittest(x, p % 64)`. + /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bittest(128, 7) // => true /// ``` public func bittest(x : Int64, p : Nat) : Bool { @@ -401,9 +523,7 @@ module { /// If `p >= 64`, the semantics is the same as for `bitset(x, p % 64)`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitset(0, 7) // => +128 /// ``` public func bitset(x : Int64, p : Nat) : Int64 { @@ -414,9 +534,7 @@ module { /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitclear(-1, 7) // => -129 /// ``` public func bitclear(x : Int64, p : Nat) : Int64 { @@ -427,9 +545,7 @@ module { /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitflip(255, 7) // => +127 /// ``` public func bitflip(x : Int64, p : Nat) : Int64 { @@ -439,9 +555,7 @@ module { /// Returns the count of non-zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitcountNonZero(0xffff) // => +16 /// ``` public let bitcountNonZero : (x : Int64) -> Int64 = Prim.popcntInt64; @@ -449,9 +563,7 @@ module { /// Returns the count of leading zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitcountLeadingZero(0x8000_0000) // => +32 /// ``` public let bitcountLeadingZero : (x : Int64) -> Int64 = Prim.clzInt64; @@ -459,9 +571,7 @@ module { /// Returns the count of trailing zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.bitcountTrailingZero(0x0201_0000) // => +16 /// ``` public let bitcountTrailingZero : (x : Int64) -> Int64 = Prim.ctzInt64; @@ -470,39 +580,45 @@ module { /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.addWrap(2 ** 62, 2 ** 62) // => -9_223_372_036_854_775_808 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+%` + /// as a function value at the moment. public func addWrap(x : Int64, y : Int64) : Int64 { x +% y }; /// Returns the difference of `x` and `y`, `x -% y`. /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.subWrap(-2 ** 63, 1) // => +9_223_372_036_854_775_807 // underflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-%` + /// as a function value at the moment. public func subWrap(x : Int64, y : Int64) : Int64 { x -% y }; /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow. /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.mulWrap(2 ** 32, 2 ** 32) // => 0 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*%` + /// as a function value at the moment. public func mulWrap(x : Int64, y : Int64) : Int64 { x *% y }; /// Returns `x` to the power of `y`, `x **% y`. @@ -510,13 +626,14 @@ module { /// Wraps on overflow/underflow. /// Traps if `y < 0 or y >= 64`. /// - /// /// Example: - /// ```motoko - /// import Int64 "mo:base/Int64"; - /// + /// ```motoko include=import /// Int64.powWrap(2, 63) // => -9_223_372_036_854_775_808 // overflow /// ``` - public func powWrap(x : Int64, y : Int64) : Int64 { x **% y }; - + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**%` + /// as a function value at the moment. + public func powWrap(x : Int64, y : Int64) : Int64 { x **% y } } diff --git a/src/Int8.mo b/src/Int8.mo index 4f7a2857..2c8d4d86 100644 --- a/src/Int8.mo +++ b/src/Int8.mo @@ -1,7 +1,11 @@ -/// 8-bit signed integers with checked arithmetic. +/// Provides utility functions on 8-bit signed integers. /// -/// Common 8-bit integer functions. -/// Most operations are available as built-in operators (e.g. `1 + 1`). +/// Note that most operations are available as built-in operators (e.g. `1 + 1`). +/// +/// Import from the base library to use this module. +/// ```motoko name=import +/// import Int8 "mo:base/Int8"; +/// ``` import Int "Int"; import Prim "mo:⛔"; @@ -11,53 +15,73 @@ module { public type Int8 = Prim.Types.Int8; /// Minimum 8-bit integer value, `-2 ** 7`. + /// + /// Example: + /// ```motoko include=import + /// Int8.minimumValue // => -128 + /// ``` public let minimumValue = -128 : Int8; /// Maximum 8-bit integer value, `+2 ** 7 - 1`. + /// + /// Example: + /// ```motoko include=import + /// Int8.maximumValue // => +127 + /// ``` public let maximumValue = 127 : Int8; - /// Converts a 8-bit signed integer to a signed integer with infinite precision. + /// Converts an 8-bit signed integer to a signed integer with infinite precision. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.toInt(123) // => 123 : Int /// ``` public let toInt : Int8 -> Int = Prim.int8ToInt; - /// Converts a signed integer with infinite precision to a 8-bit signed integer. + /// Converts a signed integer with infinite precision to an 8-bit signed integer. /// /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.fromInt(123) // => +123 : Int8 /// ``` public let fromInt : Int -> Int8 = Prim.intToInt8; - /// Converts a signed integer with infinite precision to a 8-bit signed integer. + /// Converts a signed integer with infinite precision to an 8-bit signed integer. /// /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.fromIntWrap(-123) // => -123 : Int /// ``` public let fromIntWrap : Int -> Int8 = Prim.intToInt8Wrap; + /// Converts a 16-bit signed integer to an 8-bit signed integer. + /// + /// Traps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Int8.fromInt16(123) // => +123 : Int8 + /// ``` + public let fromInt16 : Int16 -> Int8 = Prim.int16ToInt8; + + /// Converts an 8-bit signed integer to a 16-bit signed integer. + /// + /// Example: + /// ```motoko include=import + /// Int8.toInt16(123) // => +123 : Int16 + /// ``` + public let toInt16 : Int8 -> Int16 = Prim.int8ToInt16; + /// Converts an unsigned 8-bit integer to a signed 8-bit integer. /// /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.fromNat8(123) // => +123 : Int8 /// ``` public let fromNat8 : Nat8 -> Int8 = Prim.nat8ToInt8; @@ -67,20 +91,15 @@ module { /// Wraps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.toNat8(-1) // => 255 : Nat8 // underflow /// ``` public let toNat8 : Int8 -> Nat8 = Prim.int8ToNat8; - /// Returns the Text representation of `x`. - /// Formats the integer in decimal representation. + /// Converts an integer number to its textual representation. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.toText(-123) // => "-123" /// ``` public func toText(x : Int8) : Text { @@ -92,9 +111,7 @@ module { /// Traps when `x == -2 ** 7` (the minimum `Int8` value). /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.abs(-123) // => +123 /// ``` public func abs(x : Int8) : Int8 { @@ -104,9 +121,7 @@ module { /// Returns the minimum of `x` and `y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.min(+2, -3) // => -3 /// ``` public func min(x : Int8, y : Int8) : Int8 { @@ -116,82 +131,122 @@ module { /// Returns the maximum of `x` and `y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.max(+2, -3) // => +2 /// ``` public func max(x : Int8, y : Int8) : Int8 { if (x < y) { y } else { x } }; - /// Returns `x == y`. + /// Equality function for Int8 types. + /// This is equivalent to `x == y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; + /// ```motoko include=import + /// Int8.equal(-1, -1); // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `==` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `==` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Buffer "mo:base/Buffer"; /// - /// Int8.equal(123, 123) // => true + /// let buffer1 = Buffer.Buffer(1); + /// buffer1.add(-3); + /// let buffer2 = Buffer.Buffer(1); + /// buffer2.add(-3); + /// Buffer.equal(buffer1, buffer2, Int8.equal) // => true /// ``` public func equal(x : Int8, y : Int8) : Bool { x == y }; - /// Returns `x != y`. + /// Inequality function for Int8 types. + /// This is equivalent to `x != y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// - /// Int8.notEqual(123, 123) // => false + /// ```motoko include=import + /// Int8.notEqual(-1, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `!=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `!=` + /// as a function value at the moment. public func notEqual(x : Int8, y : Int8) : Bool { x != y }; - /// Returns `x < y`. + /// "Less than" function for Int8 types. + /// This is equivalent to `x < y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// - /// Int8.less(123, 124) // => true + /// ```motoko include=import + /// Int8.less(-2, 1); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<` + /// as a function value at the moment. public func less(x : Int8, y : Int8) : Bool { x < y }; - /// Returns `x <= y`. + /// "Less than or equal" function for Int8 types. + /// This is equivalent to `x <= y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// - /// Int8.lessOrEqual(123, 124) // => true + /// ```motoko include=import + /// Int8.lessOrEqual(-2, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<=` + /// as a function value at the moment. public func lessOrEqual(x : Int8, y : Int8) : Bool { x <= y }; - /// Returns `x > y`. + /// "Greater than" function for Int8 types. + /// This is equivalent to `x > y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// - /// Int8.greater(124, 123) // => true + /// ```motoko include=import + /// Int8.greater(-2, -3); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>` + /// as a function value at the moment. public func greater(x : Int8, y : Int8) : Bool { x > y }; - /// Returns `x >= y`. + /// "Greater than or equal" function for Int8 types. + /// This is equivalent to `x >= y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// - /// Int8.greaterOrEqual(124, 123) // => true + /// ```motoko include=import + /// Int8.greaterOrEqual(-2, -2); // => true /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>=` + /// as a function value at the moment. public func greaterOrEqual(x : Int8, y : Int8) : Bool { x >= y }; - /// Returns the order of `x` and `y`. + /// General-purpose comparison function for `Int8`. Returns the `Order` ( + /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; + /// ```motoko include=import + /// Int8.compare(-3, 2) // => #less + /// ``` + /// + /// This function can be used as value for a high order function, such as a sort function. /// - /// Int8.compare(123, 124) // => #less + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.sort([1, -2, -3] : [Int8], Int8.compare) // => [-3, -2, 1] /// ``` public func compare(x : Int8, y : Int8) : { #less; #equal; #greater } { if (x < y) { #less } else if (x == y) { #equal } else { #greater } @@ -201,13 +256,15 @@ module { /// /// Traps on overflow, i.e. for `neg(-2 ** 7)`. /// - /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.neg(123) // => -123 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. public func neg(x : Int8) : Int8 { -x }; /// Returns the sum of `x` and `y`, `x + y`. @@ -215,11 +272,20 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.add(100, 23) // => +123 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 0, Int8.add) // => -4 + /// ``` public func add(x : Int8, y : Int8) : Int8 { x + y }; /// Returns the difference of `x` and `y`, `x - y`. @@ -227,11 +293,20 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.sub(123, 23) // => +100 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 0, Int8.sub) // => 4 + /// ``` public func sub(x : Int8, y : Int8) : Int8 { x - y }; /// Returns the product of `x` and `y`, `x * y`. @@ -239,11 +314,20 @@ module { /// Traps on overflow/underflow. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.mul(12, 10) // => +120 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([1, -2, -3], 1, Int8.mul) // => 6 + /// ``` public func mul(x : Int8, y : Int8) : Int8 { x * y }; /// Returns the signed integer division of `x` by `y`, `x / y`. @@ -252,11 +336,14 @@ module { /// Traps when `y` is zero. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.div(123, 10) // => +12 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `/` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `/` + /// as a function value at the moment. public func div(x : Int8, y : Int8) : Int8 { x / y }; /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`, @@ -265,11 +352,14 @@ module { /// Traps when `y` is zero. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.rem(123, 10) // => +3 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `%` + /// as a function value at the moment. public func rem(x : Int8, y : Int8) : Int8 { x % y }; /// Returns `x` to the power of `y`, `x ** y`. @@ -277,51 +367,66 @@ module { /// Traps on overflow/underflow and when `y < 0 or y >= 8`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.pow(2, 6) // => +64 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**` + /// as a function value at the moment. public func pow(x : Int8, y : Int8) : Int8 { x ** y }; /// Returns the bitwise negation of `x`, `^x`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitnot(-16 /* 0xf0 */) // => +15 // 0x0f /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitnot(x : Int8) : Int8 { ^x }; /// Returns the bitwise "and" of `x` and `y`, `x & y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitand(0x1f, 0x70) // => +16 // 0x10 /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `&` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `&` + /// as a function value at the moment. public func bitand(x : Int8, y : Int8) : Int8 { x & y }; /// Returns the bitwise "or" of `x` and `y`, `x | y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitor(0x0f, 0x70) // => +127 // 0x7f /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `|` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `|` + /// as a function value at the moment. public func bitor(x : Int8, y : Int8) : Int8 { x | y }; /// Returns the bitwise "exclusive or" of `x` and `y`, `x ^ y`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitxor(0x70, 0x7f) // => +15 // 0x0f /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitxor(x : Int8, y : Int8) : Int8 { x ^ y }; /// Returns the bitwise left shift of `x` by `y`, `x << y`. @@ -332,11 +437,14 @@ module { /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 8)`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitshiftLeft(1, 4) // => +16 // 0x10 equivalent to `2 ** 4`. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<` + /// as a function value at the moment. public func bitshiftLeft(x : Int8, y : Int8) : Int8 { x << y }; /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`. @@ -347,11 +455,14 @@ module { /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 8)`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitshiftRight(64, 4) // => +4 // equivalent to `64 / (2 ** 4)` /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>>` + /// as a function value at the moment. public func bitshiftRight(x : Int8, y : Int8) : Int8 { x >> y }; /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`. @@ -362,11 +473,14 @@ module { /// For `y >= 8`, the semantics is the same as for `bitrotLeft(x, y % 8)`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitrotLeft(0x11 /* 0b0001_0001 */, 2) // => +68 // 0b0100_0100 == 0x44. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<>` + /// as a function value at the moment. public func bitrotLeft(x : Int8, y : Int8) : Int8 { x <<> y }; /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`. @@ -377,20 +491,22 @@ module { /// For `y >= 8`, the semantics is the same as for `bitrotRight(x, y % 8)`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitrotRight(0x11 /* 0b0001_0001 */, 1) // => -120 // 0b1000_1000 == 0x88. /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<>>` + /// as a function value at the moment. public func bitrotRight(x : Int8, y : Int8) : Int8 { x <>> y }; /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`. /// If `p >= 8`, the semantics is the same as for `bittest(x, p % 8)`. + /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bittest(64, 6) // => true /// ``` public func bittest(x : Int8, p : Nat) : Bool { @@ -401,9 +517,7 @@ module { /// If `p >= 8`, the semantics is the same as for `bitset(x, p % 8)`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitset(0, 6) // => +64 /// ``` public func bitset(x : Int8, p : Nat) : Int8 { @@ -414,9 +528,7 @@ module { /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitclear(-1, 6) // => -65 /// ``` public func bitclear(x : Int8, p : Nat) : Int8 { @@ -427,9 +539,7 @@ module { /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitflip(127, 6) // => +63 /// ``` public func bitflip(x : Int8, p : Nat) : Int8 { @@ -439,9 +549,7 @@ module { /// Returns the count of non-zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitcountNonZero(0x0f) // => +4 /// ``` public let bitcountNonZero : (x : Int8) -> Int8 = Prim.popcntInt8; @@ -449,9 +557,7 @@ module { /// Returns the count of leading zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitcountLeadingZero(0x08) // => +4 /// ``` public let bitcountLeadingZero : (x : Int8) -> Int8 = Prim.clzInt8; @@ -459,9 +565,7 @@ module { /// Returns the count of trailing zero bits in `x`. /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.bitcountTrailingZero(0x10) // => +4 /// ``` public let bitcountTrailingZero : (x : Int8) -> Int8 = Prim.ctzInt8; @@ -470,39 +574,45 @@ module { /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.addWrap(2 ** 6, 2 ** 6) // => -128 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+%` + /// as a function value at the moment. public func addWrap(x : Int8, y : Int8) : Int8 { x +% y }; /// Returns the difference of `x` and `y`, `x -% y`. /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.subWrap(-2 ** 7, 1) // => +127 // underflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-%` + /// as a function value at the moment. public func subWrap(x : Int8, y : Int8) : Int8 { x -% y }; /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow. /// /// Wraps on overflow/underflow. /// - /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.mulWrap(2 ** 4, 2 ** 4) // => 0 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*%` + /// as a function value at the moment. public func mulWrap(x : Int8, y : Int8) : Int8 { x *% y }; /// Returns `x` to the power of `y`, `x **% y`. @@ -510,13 +620,15 @@ module { /// Wraps on overflow/underflow. /// Traps if `y < 0 or y >= 8`. /// - /// /// Example: - /// ```motoko - /// import Int8 "mo:base/Int8"; - /// + /// ```motoko include=import /// Int8.powWrap(2, 7) // => -128 // overflow /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**%` + /// as a function value at the moment. public func powWrap(x : Int8, y : Int8) : Int8 { x **% y }; } diff --git a/src/Nat16.mo b/src/Nat16.mo index 78193a19..f8ca1a28 100644 --- a/src/Nat16.mo +++ b/src/Nat16.mo @@ -1,6 +1,11 @@ -/// 16-bit unsigned integers with checked arithmetic +/// Provides utility functions on 16-bit unsigned integers. /// -/// Most operations are available as built-in operators (e.g. `1 + 1`). +/// Note that most operations are available as built-in operators (e.g. `1 + 1`). +/// +/// Import from the base library to use this module. +/// ```motoko name=import +/// import Nat16 "mo:base/Nat16"; +/// ``` import Nat "Nat"; import Prim "mo:⛔"; @@ -9,136 +14,564 @@ module { /// 16-bit natural numbers. public type Nat16 = Prim.Types.Nat16; - /// Conversion. + /// Maximum 16-bit natural number. `2 ** 16 - 1`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.maximumValue; // => 65536 : Nat16 + /// ``` + public let maximumValue = 65535 : Nat16; + + /// Converts a 16-bit unsigned integer to an unsigned integer with infinite precision. + /// + /// Example: + /// ```motoko include=import + /// Nat16.toNat(123); // => 123 : Nat + /// ``` public let toNat : Nat16 -> Nat = Prim.nat16ToNat; - /// Conversion. Traps on overflow/underflow. + /// Converts an unsigned integer with infinite precision to a 16-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat16.fromNat(123); // => 123 : Nat16 + /// ``` public let fromNat : Nat -> Nat16 = Prim.natToNat16; - /// Conversion. Wraps on overflow/underflow. + /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer. + /// + /// Example: + /// ```motoko include=import + /// Nat16.fromNat8(123); // => 123 : Nat16 + /// ``` + public func fromNat8(x : Nat8) : Nat16 { + Prim.nat8ToNat16(x) + }; + + /// Converts a 16-bit unsigned integer to an 8-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat16.toNat8(123); // => 123 : Nat8 + /// ``` + public func toNat8(x : Nat16) : Nat8 { + Prim.nat16ToNat8(x) + }; + + /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat16.fromNat32(123); // => 123 : Nat16 + /// ``` + public func fromNat32(x : Nat32) : Nat16 { + Prim.nat32ToNat16(x) + }; + + /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer. + /// + /// Example: + /// ```motoko include=import + /// Nat16.toNat32(123); // => 123 : Nat32 + /// ``` + public func toNat32(x : Nat16) : Nat32 { + Prim.nat16ToNat32(x) + }; + + /// Converts a signed integer with infinite precision to a 16-bit unsigned integer. + /// + /// Wraps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Nat16.fromIntWrap(123 : Int); // => 123 : Nat16 + /// ``` public let fromIntWrap : Int -> Nat16 = Prim.intToNat16Wrap; - /// Returns the Text representation of `x`. + /// Converts `x` to its textual representation. Textual representation _do not_ + /// contain underscores to represent commas. + /// + /// Example: + /// ```motoko include=import + /// Nat16.toText(1234); // => "1234" : Text + /// ``` public func toText(x : Nat16) : Text { Nat.toText(toNat(x)) }; /// Returns the minimum of `x` and `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.min(123, 200); // => 123 : Nat16 + /// ``` public func min(x : Nat16, y : Nat16) : Nat16 { if (x < y) { x } else { y } }; /// Returns the maximum of `x` and `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.max(123, 200); // => 200 : Nat16 + /// ``` public func max(x : Nat16, y : Nat16) : Nat16 { if (x < y) { y } else { x } }; - /// Returns `x == y`. + /// Equality function for Nat16 types. + /// This is equivalent to `x == y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.equal(1, 1); // => true + /// (1 : Nat16) == (1 : Nat16) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `==` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `==` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Buffer "mo:base/Buffer"; + /// + /// let buffer1 = Buffer.Buffer(3); + /// let buffer2 = Buffer.Buffer(3); + /// Buffer.equal(buffer1, buffer2, Nat16.equal) // => true + /// ``` public func equal(x : Nat16, y : Nat16) : Bool { x == y }; - /// Returns `x != y`. + /// Inequality function for Nat16 types. + /// This is equivalent to `x != y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.notEqual(1, 2); // => true + /// (1 : Nat16) != (2 : Nat16) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `!=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `!=` + /// as a function value at the moment. public func notEqual(x : Nat16, y : Nat16) : Bool { x != y }; - /// Returns `x < y`. + /// "Less than" function for Nat16 types. + /// This is equivalent to `x < y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.less(1, 2); // => true + /// (1 : Nat16) < (2 : Nat16) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<` + /// as a function value at the moment. public func less(x : Nat16, y : Nat16) : Bool { x < y }; - /// Returns `x <= y`. + /// "Less than or equal" function for Nat16 types. + /// This is equivalent to `x <= y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.lessOrEqual(1, 2); // => true + /// (1 : Nat16) <= (2 : Nat16) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<=` + /// as a function value at the moment. public func lessOrEqual(x : Nat16, y : Nat16) : Bool { x <= y }; - /// Returns `x > y`. + /// "Greater than" function for Nat16 types. + /// This is equivalent to `x > y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.greater(2, 1); // => true + /// (2 : Nat16) > (1 : Nat16) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>` + /// as a function value at the moment. public func greater(x : Nat16, y : Nat16) : Bool { x > y }; - /// Returns `x >= y`. + /// "Greater than or equal" function for Nat16 types. + /// This is equivalent to `x >= y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.greaterOrEqual(2, 1); // => true + /// (2 : Nat16) >= (1 : Nat16) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>=` + /// as a function value at the moment. public func greaterOrEqual(x : Nat16, y : Nat16) : Bool { x >= y }; - /// Returns the order of `x` and `y`. + /// General purpose comparison function for `Nat16`. Returns the `Order` ( + /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.compare(2, 3) // => #less + /// ``` + /// + /// This function can be used as value for a high order function, such as a sort function. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.sort([2, 3, 1] : [Nat16], Nat16.compare) // => [1, 2, 3] + /// ``` public func compare(x : Nat16, y : Nat16) : { #less; #equal; #greater } { if (x < y) { #less } else if (x == y) { #equal } else { #greater } }; - /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow. + /// Returns the sum of `x` and `y`, `x + y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.add(1, 2); // => 3 + /// (1 : Nat16) + (2 : Nat16) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 0, Nat16.add) // => 6 + /// ``` public func add(x : Nat16, y : Nat16) : Nat16 { x + y }; - /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow. + /// Returns the difference of `x` and `y`, `x - y`. + /// Traps on underflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.sub(2, 1); // => 1 + /// (2 : Nat16) - (1 : Nat16) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 20, Nat16.sub) // => 14 + /// ``` public func sub(x : Nat16, y : Nat16) : Nat16 { x - y }; - /// Returns the product of `x` and `y`, `x * y`. Traps on overflow. + /// Returns the product of `x` and `y`, `x * y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.mul(2, 3); // => 6 + /// (2 : Nat16) * (3 : Nat16) // => 6 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 1, Nat16.mul) // => 6 + /// ``` public func mul(x : Nat16, y : Nat16) : Nat16 { x * y }; - /// Returns the division of `x by y`, `x / y`. + /// Returns the quotient of `x` divided by `y`, `x / y`. /// Traps when `y` is zero. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.div(6, 2); // => 3 + /// (6 : Nat16) / (2 : Nat16) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `/` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `/` + /// as a function value at the moment. public func div(x : Nat16, y : Nat16) : Nat16 { x / y }; /// Returns the remainder of `x` divided by `y`, `x % y`. /// Traps when `y` is zero. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.rem(6, 4); // => 2 + /// (6 : Nat16) % (4 : Nat16) // => 2 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `%` + /// as a function value at the moment. public func rem(x : Nat16, y : Nat16) : Nat16 { x % y }; - /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow. + /// Returns the power of `x` to `y`, `x ** y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.pow(2, 3); // => 8 + /// (2 : Nat16) ** (3 : Nat16) // => 8 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**` + /// as a function value at the moment. public func pow(x : Nat16, y : Nat16) : Nat16 { x ** y }; /// Returns the bitwise negation of `x`, `^x`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.bitnot(0); // => 65535 + /// ^(0 : Nat16) // => 65535 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitnot(x : Nat16) : Nat16 { ^x }; /// Returns the bitwise and of `x` and `y`, `x & y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.bitand(0, 1); // => 0 + /// (0 : Nat16) & (1 : Nat16) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `&` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `&` + /// as a function value at the moment. public func bitand(x : Nat16, y : Nat16) : Nat16 { x & y }; - /// Returns the bitwise or of `x` and `y`, `x \| y`. + /// Returns the bitwise or of `x` and `y`, `x | y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.bitor(0, 1); // => 1 + /// (0 : Nat16) | (1 : Nat16) // => 1 + /// ``` public func bitor(x : Nat16, y : Nat16) : Nat16 { x | y }; /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.bitxor(0, 1); // => 1 + /// (0 : Nat16) ^ (1 : Nat16) // => 1 + /// ``` public func bitxor(x : Nat16, y : Nat16) : Nat16 { x ^ y }; /// Returns the bitwise shift left of `x` by `y`, `x << y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.bitshiftLeft(1, 3); // => 8 + /// (1 : Nat16) << (3 : Nat16) // => 8 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<` + /// as a function value at the moment. public func bitshiftLeft(x : Nat16, y : Nat16) : Nat16 { x << y }; /// Returns the bitwise shift right of `x` by `y`, `x >> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.bitshiftRight(8, 3); // => 1 + /// (8 : Nat16) >> (3 : Nat16) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>>` + /// as a function value at the moment. public func bitshiftRight(x : Nat16, y : Nat16) : Nat16 { x >> y }; /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.bitrotLeft(2, 1); // => 4 + /// (2 : Nat16) <<> (1 : Nat16) // => 4 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<>` + /// as a function value at the moment. public func bitrotLeft(x : Nat16, y : Nat16) : Nat16 { x <<> y }; /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.bitrotRight(1, 1); // => 32768 + /// (1 : Nat16) <>> (1 : Nat16) // => 32768 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<>>` + /// as a function value at the moment. public func bitrotRight(x : Nat16, y : Nat16) : Nat16 { x <>> y }; /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`. + /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing. + /// + /// Example: + /// ```motoko include=import + /// Nat16.bittest(5, 2); // => true + /// ``` public func bittest(x : Nat16, p : Nat) : Bool { Prim.btstNat16(x, Prim.natToNat16(p)) }; /// Returns the value of setting bit `p mod 16` in `x` to `1`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.bitset(0, 2); // => 4 + /// ``` public func bitset(x : Nat16, p : Nat) : Nat16 { x | (1 << Prim.natToNat16(p)) }; /// Returns the value of clearing bit `p mod 16` in `x` to `0`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.bitclear(5, 2); // => 1 + /// ``` public func bitclear(x : Nat16, p : Nat) : Nat16 { x & ^(1 << Prim.natToNat16(p)) }; /// Returns the value of flipping bit `p mod 16` in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.bitflip(5, 2); // => 1 + /// ``` public func bitflip(x : Nat16, p : Nat) : Nat16 { x ^ (1 << Prim.natToNat16(p)) }; /// Returns the count of non-zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.bitcountNonZero(5); // => 2 + /// ``` public let bitcountNonZero : (x : Nat16) -> Nat16 = Prim.popcntNat16; /// Returns the count of leading zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.bitcountLeadingZero(5); // => 13 + /// ``` public let bitcountLeadingZero : (x : Nat16) -> Nat16 = Prim.clzNat16; /// Returns the count of trailing zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat16.bitcountTrailingZero(5); // => 0 + /// ``` public let bitcountTrailingZero : (x : Nat16) -> Nat16 = Prim.ctzNat16; /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.addWrap(65532, 5); // => 1 + /// (65532 : Nat16) +% (5 : Nat16) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+%` + /// as a function value at the moment. public func addWrap(x : Nat16, y : Nat16) : Nat16 { x +% y }; /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.subWrap(1, 2); // => 65535 + /// (1 : Nat16) -% (2 : Nat16) // => 65535 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-%` + /// as a function value at the moment. public func subWrap(x : Nat16, y : Nat16) : Nat16 { x -% y }; /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.mulWrap(655, 101); // => 619 + /// (655 : Nat16) *% (101 : Nat16) // => 619 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*%` + /// as a function value at the moment. public func mulWrap(x : Nat16, y : Nat16) : Nat16 { x *% y }; /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat16.powWrap(2, 16); // => 0 + /// (2 : Nat16) **% (16 : Nat16) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**%` + /// as a function value at the moment. public func powWrap(x : Nat16, y : Nat16) : Nat16 { x **% y }; } diff --git a/src/Nat32.mo b/src/Nat32.mo index 9b7823f9..1c92ae52 100644 --- a/src/Nat32.mo +++ b/src/Nat32.mo @@ -1,6 +1,11 @@ -/// 32-bit unsigned integers with checked arithmetic +/// Provides utility functions on 32-bit unsigned integers. /// -/// Most operations are available as built-in operators (e.g. `1 + 1`). +/// Note that most operations are available as built-in operators (e.g. `1 + 1`). +/// +/// Import from the base library to use this module. +/// ```motoko name=import +/// import Nat32 "mo:base/Nat32"; +/// ``` import Nat "Nat"; import Prim "mo:⛔"; @@ -9,136 +14,573 @@ module { /// 32-bit natural numbers. public type Nat32 = Prim.Types.Nat32; - /// Conversion. + /// Maximum 32-bit natural number. `2 ** 32 - 1`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.maximumValue; // => 4294967295 : Nat32 + /// ``` + public let maximumValue = 4294967295 : Nat32; + + /// Converts a 32-bit unsigned integer to an unsigned integer with infinite precision. + /// + /// Example: + /// ```motoko include=import + /// Nat32.toNat(123); // => 123 : Nat + /// ``` public let toNat : Nat32 -> Nat = Prim.nat32ToNat; - /// Conversion. Traps on overflow/underflow. + /// Converts an unsigned integer with infinite precision to a 32-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat32.fromNat(123); // => 123 : Nat32 + /// ``` public let fromNat : Nat -> Nat32 = Prim.natToNat32; - /// Conversion. Wraps on overflow/underflow. + /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer. + /// + /// Example: + /// ```motoko include=import + /// Nat32.fromNat16(123); // => 123 : Nat32 + /// ``` + public func fromNat16(x : Nat16) : Nat32 { + Prim.nat16ToNat32(x) + }; + + /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat32.toNat16(123); // => 123 : Nat16 + /// ``` + public func toNat16(x : Nat32) : Nat16 { + Prim.nat32ToNat16(x) + }; + + /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat32.fromNat64(123); // => 123 : Nat32 + /// ``` + public func fromNat64(x : Nat64) : Nat32 { + Prim.nat64ToNat32(x) + }; + + /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer. + /// + /// Example: + /// ```motoko include=import + /// Nat32.toNat64(123); // => 123 : Nat64 + /// ``` + public func toNat64(x : Nat32) : Nat64 { + Prim.nat32ToNat64(x) + }; + + /// Converts a signed integer with infinite precision to a 32-bit unsigned integer. + /// + /// Traps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Nat32.fromIntWrap(123); // => 123 : Nat32 + /// ``` public let fromIntWrap : Int -> Nat32 = Prim.intToNat32Wrap; - /// Returns the Text representation of `x`. + /// Converts `x` to its textual representation. Textual representation _do not_ + /// contain underscores to represent commas. + /// + /// Example: + /// ```motoko include=import + /// Nat32.toText(1234); // => "1234" : Text + /// ``` public func toText(x : Nat32) : Text { Nat.toText(toNat(x)) }; /// Returns the minimum of `x` and `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.min(123, 456); // => 123 : Nat32 + /// ``` public func min(x : Nat32, y : Nat32) : Nat32 { if (x < y) { x } else { y } }; /// Returns the maximum of `x` and `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.max(123, 456); // => 456 : Nat32 + /// ``` public func max(x : Nat32, y : Nat32) : Nat32 { if (x < y) { y } else { x } }; - /// Returns `x == y`. + /// Equality function for Nat32 types. + /// This is equivalent to `x == y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.equal(1, 1); // => true + /// (1 : Nat32) == (1 : Nat32) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `==` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `==` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Buffer "mo:base/Buffer"; + /// + /// let buffer1 = Buffer.Buffer(3); + /// let buffer2 = Buffer.Buffer(3); + /// Buffer.equal(buffer1, buffer2, Nat32.equal) // => true + /// ``` public func equal(x : Nat32, y : Nat32) : Bool { x == y }; - /// Returns `x != y`. + /// Inequality function for Nat32 types. + /// This is equivalent to `x != y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.notEqual(1, 2); // => true + /// (1 : Nat32) != (2 : Nat32) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `!=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `!=` + /// as a function value at the moment. public func notEqual(x : Nat32, y : Nat32) : Bool { x != y }; - /// Returns `x < y`. + /// "Less than" function for Nat32 types. + /// This is equivalent to `x < y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.less(1, 2); // => true + /// (1 : Nat32) < (2 : Nat32) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<` + /// as a function value at the moment. public func less(x : Nat32, y : Nat32) : Bool { x < y }; - /// Returns `x <= y`. + /// "Less than or equal" function for Nat32 types. + /// This is equivalent to `x <= y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.lessOrEqual(1, 2); // => true + /// (1 : Nat32) <= (2 : Nat32) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<=` + /// as a function value at the moment. public func lessOrEqual(x : Nat32, y : Nat32) : Bool { x <= y }; - /// Returns `x > y`. + /// "Greater than" function for Nat32 types. + /// This is equivalent to `x > y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.greater(2, 1); // => true + /// (2 : Nat32) > (1 : Nat32) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>` + /// as a function value at the moment. public func greater(x : Nat32, y : Nat32) : Bool { x > y }; - /// Returns `x >= y`. + /// "Greater than or equal" function for Nat32 types. + /// This is equivalent to `x >= y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.greaterOrEqual(2, 1); // => true + /// (2 : Nat32) >= (1 : Nat32) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>=` + /// as a function value at the moment. public func greaterOrEqual(x : Nat32, y : Nat32) : Bool { x >= y }; - /// Returns the order of `x` and `y`. + /// General purpose comparison function for `Nat32`. Returns the `Order` ( + /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.compare(2, 3) // => #less + /// ``` + /// + /// This function can be used as value for a high order function, such as a sort function. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.sort([2, 3, 1] : [Nat32], Nat32.compare) // => [1, 2, 3] + /// ``` public func compare(x : Nat32, y : Nat32) : { #less; #equal; #greater } { if (x < y) { #less } else if (x == y) { #equal } else { #greater } }; - /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow. + /// Returns the sum of `x` and `y`, `x + y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.add(1, 2); // => 3 + /// (1 : Nat32) + (2 : Nat32) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 0, Nat32.add) // => 6 + /// ``` public func add(x : Nat32, y : Nat32) : Nat32 { x + y }; - /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow. + /// Returns the difference of `x` and `y`, `x - y`. + /// Traps on underflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.sub(2, 1); // => 1 + /// (2 : Nat32) - (1 : Nat32) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 20, Nat32.sub) // => 14 + /// ``` public func sub(x : Nat32, y : Nat32) : Nat32 { x - y }; - /// Returns the product of `x` and `y`, `x * y`. Traps on overflow. + /// Returns the product of `x` and `y`, `x * y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.mul(2, 3); // => 6 + /// (2 : Nat32) * (3 : Nat32) // => 6 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 1, Nat32.mul) // => 6 + /// ``` public func mul(x : Nat32, y : Nat32) : Nat32 { x * y }; /// Returns the division of `x by y`, `x / y`. /// Traps when `y` is zero. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.div(6, 2); // => 3 + /// (6 : Nat32) / (2 : Nat32) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `/` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `/` + /// as a function value at the moment. public func div(x : Nat32, y : Nat32) : Nat32 { x / y }; /// Returns the remainder of `x` divided by `y`, `x % y`. /// Traps when `y` is zero. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.rem(6, 4); // => 2 + /// (6 : Nat32) % (4 : Nat32) // => 2 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `%` + /// as a function value at the moment. public func rem(x : Nat32, y : Nat32) : Nat32 { x % y }; /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.pow(2, 3); // => 8 + /// (2 : Nat32) ** (3 : Nat32) // => 8 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**` + /// as a function value at the moment. public func pow(x : Nat32, y : Nat32) : Nat32 { x ** y }; /// Returns the bitwise negation of `x`, `^x`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.bitnot(0) // => 4294967295 + /// ^(0 : Nat32) // => 4294967295 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitnot(x : Nat32) : Nat32 { ^x }; /// Returns the bitwise and of `x` and `y`, `x & y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.bitand(1, 3); // => 1 + /// (1 : Nat32) & (3 : Nat32) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `&` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `&` + /// as a function value at the moment. public func bitand(x : Nat32, y : Nat32) : Nat32 { x & y }; - /// Returns the bitwise or of `x` and `y`, `x \| y`. + /// Returns the bitwise or of `x` and `y`, `x | y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.bitor(1, 3); // => 3 + /// (1 : Nat32) | (3 : Nat32) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `|` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `|` + /// as a function value at the moment. public func bitor(x : Nat32, y : Nat32) : Nat32 { x | y }; /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.bitxor(1, 3); // => 2 + /// (1 : Nat32) ^ (3 : Nat32) // => 2 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitxor(x : Nat32, y : Nat32) : Nat32 { x ^ y }; /// Returns the bitwise shift left of `x` by `y`, `x << y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.bitshiftLeft(1, 3); // => 8 + /// (1 : Nat32) << (3 : Nat32) // => 8 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<` + /// as a function value at the moment. public func bitshiftLeft(x : Nat32, y : Nat32) : Nat32 { x << y }; /// Returns the bitwise shift right of `x` by `y`, `x >> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.bitshiftRight(8, 3); // => 1 + /// (8 : Nat32) >> (3 : Nat32) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>>` + /// as a function value at the moment. public func bitshiftRight(x : Nat32, y : Nat32) : Nat32 { x >> y }; /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.bitrotLeft(1, 3); // => 8 + /// (1 : Nat32) <<> (3 : Nat32) // => 8 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<>` + /// as a function value at the moment. public func bitrotLeft(x : Nat32, y : Nat32) : Nat32 { x <<> y }; /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.bitrotRight(1, 1); // => 2147483648 + /// (1 : Nat32) <>> (1 : Nat32) // => 2147483648 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<>>` + /// as a function value at the moment. public func bitrotRight(x : Nat32, y : Nat32) : Nat32 { x <>> y }; /// Returns the value of bit `p mod 32` in `x`, `(x & 2^(p mod 32)) == 2^(p mod 32)`. + /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing. + /// + /// Example: + /// ```motoko include=import + /// Nat32.bittest(5, 2); // => true + /// ``` public func bittest(x : Nat32, p : Nat) : Bool { Prim.btstNat32(x, Prim.natToNat32(p)) }; /// Returns the value of setting bit `p mod 32` in `x` to `1`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.bitset(5, 1); // => 7 + /// ``` public func bitset(x : Nat32, p : Nat) : Nat32 { x | (1 << Prim.natToNat32(p)) }; /// Returns the value of clearing bit `p mod 32` in `x` to `0`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.bitclear(5, 2); // => 1 + /// ``` public func bitclear(x : Nat32, p : Nat) : Nat32 { x & ^(1 << Prim.natToNat32(p)) }; /// Returns the value of flipping bit `p mod 32` in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.bitflip(5, 2); // => 1 + /// ``` public func bitflip(x : Nat32, p : Nat) : Nat32 { x ^ (1 << Prim.natToNat32(p)) }; /// Returns the count of non-zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.bitcountNonZero(5); // => 2 + /// ``` public let bitcountNonZero : (x : Nat32) -> Nat32 = Prim.popcntNat32; /// Returns the count of leading zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.bitcountLeadingZero(5); // => 29 + /// ``` public let bitcountLeadingZero : (x : Nat32) -> Nat32 = Prim.clzNat32; /// Returns the count of trailing zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat32.bitcountTrailingZero(16); // => 4 + /// ``` public let bitcountTrailingZero : (x : Nat32) -> Nat32 = Prim.ctzNat32; /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.addWrap(4294967295, 1); // => 0 + /// (4294967295 : Nat32) +% (1 : Nat32) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+%` + /// as a function value at the moment. public func addWrap(x : Nat32, y : Nat32) : Nat32 { x +% y }; /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.subWrap(0, 1); // => 4294967295 + /// (0 : Nat32) -% (1 : Nat32) // => 4294967295 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-%` + /// as a function value at the moment. public func subWrap(x : Nat32, y : Nat32) : Nat32 { x -% y }; /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.mulWrap(2147483648, 2); // => 0 + /// (2147483648 : Nat32) *% (2 : Nat32) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*%` + /// as a function value at the moment. public func mulWrap(x : Nat32, y : Nat32) : Nat32 { x *% y }; /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat32.powWrap(2, 32); // => 0 + /// (2 : Nat32) **% (32 : Nat32) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**%` + /// as a function value at the moment. public func powWrap(x : Nat32, y : Nat32) : Nat32 { x **% y }; } diff --git a/src/Nat64.mo b/src/Nat64.mo index 6d5cda6b..3724fce4 100644 --- a/src/Nat64.mo +++ b/src/Nat64.mo @@ -1,6 +1,11 @@ -/// 64-bit unsigned integers with checked arithmetic +/// Provides utility functions on 64-bit unsigned integers. /// -/// Most operations are available as built-in operators (e.g. `1 + 1`). +/// Note that most operations are available as built-in operators (e.g. `1 + 1`). +/// +/// Import from the base library to use this module. +/// ```motoko name=import +/// import Nat64 "mo:base/Nat64"; +/// ``` import Nat "Nat"; import Prim "mo:⛔"; @@ -9,136 +14,552 @@ module { /// 64-bit natural numbers. public type Nat64 = Prim.Types.Nat64; - /// Conversion. + /// Maximum 64-bit natural number. `2 ** 64 - 1`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.maximumValue; // => 18446744073709551615 : Nat64 + /// ``` + + public let maximumValue = 18446744073709551615 : Nat64; + + /// Converts a 64-bit unsigned integer to an unsigned integer with infinite precision. + /// + /// Example: + /// ```motoko include=import + /// Nat64.toNat(123); // => 123 : Nat + /// ``` public let toNat : Nat64 -> Nat = Prim.nat64ToNat; - /// Conversion. Traps on overflow/underflow. + /// Converts an unsigned integer with infinite precision to a 64-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat64.fromNat(123); // => 123 : Nat64 + /// ``` public let fromNat : Nat -> Nat64 = Prim.natToNat64; - /// Conversion. Wraps on overflow/underflow. + /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer. + /// + /// Example: + /// ```motoko include=import + /// Nat64.fromNat32(123); // => 123 : Nat64 + /// ``` + public func fromNat32(x : Nat32) : Nat64 { + Prim.nat32ToNat64(x) + }; + + /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat64.toNat32(123); // => 123 : Nat32 + /// ``` + public func toNat32(x : Nat64) : Nat32 { + Prim.nat64ToNat32(x) + }; + + /// Converts a signed integer with infinite precision to a 64-bit unsigned integer. + /// + /// Traps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Nat64.fromIntWrap(123); // => 123 : Nat64 + /// ``` public let fromIntWrap : Int -> Nat64 = Prim.intToNat64Wrap; - /// Returns the Text representation of `x`. + /// Converts `x` to its textual representation. Textual representation _do not_ + /// contain underscores to represent commas. + /// + /// Example: + /// ```motoko include=import + /// Nat64.toText(1234); // => "1234" : Text + /// ``` public func toText(x : Nat64) : Text { Nat.toText(toNat(x)) }; /// Returns the minimum of `x` and `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.min(123, 456); // => 123 : Nat64 + /// ``` public func min(x : Nat64, y : Nat64) : Nat64 { if (x < y) { x } else { y } }; /// Returns the maximum of `x` and `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.max(123, 456); // => 456 : Nat64 + /// ``` public func max(x : Nat64, y : Nat64) : Nat64 { if (x < y) { y } else { x } }; - /// Returns `x == y`. + /// Equality function for Nat64 types. + /// This is equivalent to `x == y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.equal(1, 1); // => true + /// (1 : Nat64) == (1 : Nat64) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `==` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `==` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Buffer "mo:base/Buffer"; + /// + /// let buffer1 = Buffer.Buffer(3); + /// let buffer2 = Buffer.Buffer(3); + /// Buffer.equal(buffer1, buffer2, Nat64.equal) // => true + /// ``` public func equal(x : Nat64, y : Nat64) : Bool { x == y }; - /// Returns `x != y`. + /// Inequality function for Nat64 types. + /// This is equivalent to `x != y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.notEqual(1, 2); // => true + /// (1 : Nat64) != (2 : Nat64) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `!=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `!=` + /// as a function value at the moment. public func notEqual(x : Nat64, y : Nat64) : Bool { x != y }; - /// Returns `x < y`. + /// "Less than" function for Nat64 types. + /// This is equivalent to `x < y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.less(1, 2); // => true + /// (1 : Nat64) < (2 : Nat64) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<` + /// as a function value at the moment. public func less(x : Nat64, y : Nat64) : Bool { x < y }; - /// Returns `x <= y`. + /// "Less than or equal" function for Nat64 types. + /// This is equivalent to `x <= y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.lessOrEqual(1, 2); // => true + /// (1 : Nat64) <= (2 : Nat64) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<=` + /// as a function value at the moment. public func lessOrEqual(x : Nat64, y : Nat64) : Bool { x <= y }; - /// Returns `x > y`. + /// "Greater than" function for Nat64 types. + /// This is equivalent to `x > y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.greater(2, 1); // => true + /// (2 : Nat64) > (1 : Nat64) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>` + /// as a function value at the moment. public func greater(x : Nat64, y : Nat64) : Bool { x > y }; - /// Returns `x >= y`. + /// "Greater than or equal" function for Nat64 types. + /// This is equivalent to `x >= y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.greaterOrEqual(2, 1); // => true + /// (2 : Nat64) >= (1 : Nat64) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>=` + /// as a function value at the moment. public func greaterOrEqual(x : Nat64, y : Nat64) : Bool { x >= y }; - /// Returns the order of `x` and `y`. + /// General purpose comparison function for `Nat64`. Returns the `Order` ( + /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.compare(2, 3) // => #less + /// ``` + /// + /// This function can be used as value for a high order function, such as a sort function. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.sort([2, 3, 1] : [Nat64], Nat64.compare) // => [1, 2, 3] + /// ``` public func compare(x : Nat64, y : Nat64) : { #less; #equal; #greater } { if (x < y) { #less } else if (x == y) { #equal } else { #greater } }; - /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow. + /// Returns the sum of `x` and `y`, `x + y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.add(1, 2); // => 3 + /// (1 : Nat64) + (2 : Nat64) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 0, Nat64.add) // => 6 + /// ``` public func add(x : Nat64, y : Nat64) : Nat64 { x + y }; - /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow. + /// Returns the difference of `x` and `y`, `x - y`. + /// Traps on underflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.sub(3, 1); // => 2 + /// (3 : Nat64) - (1 : Nat64) // => 2 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 10, Nat64.sub) // => 4 + /// ``` public func sub(x : Nat64, y : Nat64) : Nat64 { x - y }; - /// Returns the product of `x` and `y`, `x * y`. Traps on overflow. + /// Returns the product of `x` and `y`, `x * y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.mul(2, 3); // => 6 + /// (2 : Nat64) * (3 : Nat64) // => 6 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 1, Nat64.mul) // => 6 + /// ``` public func mul(x : Nat64, y : Nat64) : Nat64 { x * y }; - /// Returns the division of `x by y`, `x / y`. + /// Returns the quotient of `x` divided by `y`, `x / y`. /// Traps when `y` is zero. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.div(6, 2); // => 3 + /// (6 : Nat64) / (2 : Nat64) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `/` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `/` + /// as a function value at the moment. public func div(x : Nat64, y : Nat64) : Nat64 { x / y }; /// Returns the remainder of `x` divided by `y`, `x % y`. /// Traps when `y` is zero. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.rem(6, 4); // => 2 + /// (6 : Nat64) % (4 : Nat64) // => 2 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `%` + /// as a function value at the moment. public func rem(x : Nat64, y : Nat64) : Nat64 { x % y }; /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.pow(2, 3); // => 8 + /// (2 : Nat64) ** (3 : Nat64) // => 8 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**` + /// as a function value at the moment. public func pow(x : Nat64, y : Nat64) : Nat64 { x ** y }; /// Returns the bitwise negation of `x`, `^x`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.bitnot(0); // => 18446744073709551615 + /// ^(0 : Nat64) // => 18446744073709551615 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitnot(x : Nat64) : Nat64 { ^x }; /// Returns the bitwise and of `x` and `y`, `x & y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.bitand(1, 3); // => 1 + /// (1 : Nat64) & (3 : Nat64) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `&` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `&` + /// as a function value at the moment. public func bitand(x : Nat64, y : Nat64) : Nat64 { x & y }; - /// Returns the bitwise or of `x` and `y`, `x \| y`. + /// Returns the bitwise or of `x` and `y`, `x | y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.bitor(1, 3); // => 3 + /// (1 : Nat64) | (3 : Nat64) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `|` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `|` + /// as a function value at the moment. public func bitor(x : Nat64, y : Nat64) : Nat64 { x | y }; /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.bitxor(1, 3); // => 2 + /// (1 : Nat64) ^ (3 : Nat64) // => 2 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitxor(x : Nat64, y : Nat64) : Nat64 { x ^ y }; /// Returns the bitwise shift left of `x` by `y`, `x << y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.bitshiftLeft(1, 3); // => 8 + /// (1 : Nat64) << (3 : Nat64) // => 8 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<` + /// as a function value at the moment. public func bitshiftLeft(x : Nat64, y : Nat64) : Nat64 { x << y }; /// Returns the bitwise shift right of `x` by `y`, `x >> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.bitshiftRight(8, 3); // => 1 + /// (8 : Nat64) >> (3 : Nat64) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>>` + /// as a function value at the moment. public func bitshiftRight(x : Nat64, y : Nat64) : Nat64 { x >> y }; /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.bitrotLeft(1, 3); // => 8 + /// (1 : Nat64) <<> (3 : Nat64) // => 8 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<>` + /// as a function value at the moment. public func bitrotLeft(x : Nat64, y : Nat64) : Nat64 { x <<> y }; /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.bitrotRight(8, 3); // => 1 + /// (8 : Nat64) <>> (3 : Nat64) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<>>` + /// as a function value at the moment. public func bitrotRight(x : Nat64, y : Nat64) : Nat64 { x <>> y }; /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`. + /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing. + /// + /// Example: + /// ```motoko include=import + /// Nat64.bittest(5, 2); // => true + /// ``` public func bittest(x : Nat64, p : Nat) : Bool { Prim.btstNat64(x, Prim.natToNat64(p)) }; /// Returns the value of setting bit `p mod 64` in `x` to `1`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.bitset(5, 1); // => 7 + /// ``` public func bitset(x : Nat64, p : Nat) : Nat64 { x | (1 << Prim.natToNat64(p)) }; /// Returns the value of clearing bit `p mod 64` in `x` to `0`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.bitclear(5, 2); // => 1 + /// ``` public func bitclear(x : Nat64, p : Nat) : Nat64 { x & ^(1 << Prim.natToNat64(p)) }; /// Returns the value of flipping bit `p mod 64` in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.bitflip(5, 2); // => 1 + /// ``` public func bitflip(x : Nat64, p : Nat) : Nat64 { x ^ (1 << Prim.natToNat64(p)) }; /// Returns the count of non-zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.bitcountNonZero(5); // => 2 + /// ``` public let bitcountNonZero : (x : Nat64) -> Nat64 = Prim.popcntNat64; /// Returns the count of leading zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.bitcountLeadingZero(5); // => 61 + /// ``` public let bitcountLeadingZero : (x : Nat64) -> Nat64 = Prim.clzNat64; /// Returns the count of trailing zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat64.bitcountTrailingZero(16); // => 4 + /// ``` public let bitcountTrailingZero : (x : Nat64) -> Nat64 = Prim.ctzNat64; /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.addWrap(Nat64.maximumValue, 1); // => 0 + /// Nat64.maximumValue +% (1 : Nat64) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+%` + /// as a function value at the moment. public func addWrap(x : Nat64, y : Nat64) : Nat64 { x +% y }; /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.subWrap(0, 1); // => 18446744073709551615 + /// (0 : Nat64) -% (1 : Nat64) // => 18446744073709551615 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-%` + /// as a function value at the moment. public func subWrap(x : Nat64, y : Nat64) : Nat64 { x -% y }; /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.mulWrap(4294967296, 4294967296); // => 0 + /// (4294967296 : Nat64) *% (4294967296 : Nat64) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*%` + /// as a function value at the moment. public func mulWrap(x : Nat64, y : Nat64) : Nat64 { x *% y }; /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat64.powWrap(2, 64); // => 0 + /// (2 : Nat64) **% (64 : Nat64) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**%` + /// as a function value at the moment. public func powWrap(x : Nat64, y : Nat64) : Nat64 { x **% y }; } diff --git a/src/Nat8.mo b/src/Nat8.mo index fad0a448..540991d1 100644 --- a/src/Nat8.mo +++ b/src/Nat8.mo @@ -1,6 +1,11 @@ -/// 8-bit unsigned integers with checked arithmetic +/// Provides utility functions on 8-bit unsigned integers. /// -/// Most operations are available as built-in operators (e.g. `1 + 1`). +/// Note that most operations are available as built-in operators (e.g. `1 + 1`). +/// +/// Import from the base library to use this module. +/// ```motoko name=import +/// import Nat8 "mo:base/Nat8"; +/// ``` import Nat "Nat"; import Prim "mo:⛔"; @@ -9,136 +14,546 @@ module { /// 8-bit natural numbers. public type Nat8 = Prim.Types.Nat8; - /// Conversion. + /// Maximum 8-bit natural number. `2 ** 8 - 1`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.maximumValue; // => 255 : Nat8 + /// ``` + public let maximumValue = 255 : Nat8; + + /// Converts an 8-bit unsigned integer to an unsigned integer with infinite precision. + /// + /// Example: + /// ```motoko include=import + /// Nat8.toNat(123); // => 123 : Nat + /// ``` public let toNat : Nat8 -> Nat = Prim.nat8ToNat; - /// Conversion. Traps on overflow/underflow. + /// Converts an unsigned integer with infinite precision to an 8-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat8.fromNat(123); // => 123 : Nat8 + /// ``` public let fromNat : Nat -> Nat8 = Prim.natToNat8; - /// Conversion. Wraps on overflow/underflow. + /// Converts a 16-bit unsigned integer to a 8-bit unsigned integer. + /// + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// Nat8.fromNat16(123); // => 123 : Nat8 + /// ``` + public let fromNat16 : Nat16 -> Nat8 = Prim.nat16ToNat8; + + /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer. + /// + /// Example: + /// ```motoko include=import + /// Nat8.toNat16(123); // => 123 : Nat16 + /// ``` + public let toNat16 : Nat8 -> Nat16 = Prim.nat8ToNat16; + + /// Converts a signed integer with infinite precision to an 8-bit unsigned integer. + /// + /// Wraps on overflow/underflow. + /// + /// Example: + /// ```motoko include=import + /// Nat8.fromIntWrap(123); // => 123 : Nat8 + /// ``` public let fromIntWrap : Int -> Nat8 = Prim.intToNat8Wrap; - /// Returns the Text representation of `x`. + /// Converts `x` to its textual representation. + /// + /// Example: + /// ```motoko include=import + /// Nat8.toText(123); // => "123" : Text + /// ``` public func toText(x : Nat8) : Text { Nat.toText(toNat(x)) }; /// Returns the minimum of `x` and `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.min(123, 200); // => 123 : Nat8 + /// ``` public func min(x : Nat8, y : Nat8) : Nat8 { if (x < y) { x } else { y } }; /// Returns the maximum of `x` and `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.max(123, 200); // => 200 : Nat8 + /// ``` public func max(x : Nat8, y : Nat8) : Nat8 { if (x < y) { y } else { x } }; - /// Returns `x == y`. + /// Equality function for Nat8 types. + /// This is equivalent to `x == y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.equal(1, 1); // => true + /// (1 : Nat8) == (1 : Nat8) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `==` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `==` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Buffer "mo:base/Buffer"; + /// + /// let buffer1 = Buffer.Buffer(3); + /// let buffer2 = Buffer.Buffer(3); + /// Buffer.equal(buffer1, buffer2, Nat8.equal) // => true + /// ``` public func equal(x : Nat8, y : Nat8) : Bool { x == y }; - /// Returns `x != y`. + /// Inequality function for Nat8 types. + /// This is equivalent to `x != y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.notEqual(1, 2); // => true + /// (1 : Nat8) != (2 : Nat8) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `!=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `!=` + /// as a function value at the moment. public func notEqual(x : Nat8, y : Nat8) : Bool { x != y }; - /// Returns `x < y`. + /// "Less than" function for Nat8 types. + /// This is equivalent to `x < y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.less(1, 2); // => true + /// (1 : Nat8) < (2 : Nat8) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<` + /// as a function value at the moment. public func less(x : Nat8, y : Nat8) : Bool { x < y }; - /// Returns `x <= y`. + /// "Less than or equal" function for Nat8 types. + /// This is equivalent to `x <= y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat.lessOrEqual(1, 2); // => true + /// 1 <= 2 // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<=` + /// as a function value at the moment. public func lessOrEqual(x : Nat8, y : Nat8) : Bool { x <= y }; - /// Returns `x > y`. + /// "Greater than" function for Nat8 types. + /// This is equivalent to `x > y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.greater(2, 1); // => true + /// (2 : Nat8) > (1 : Nat8) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>` + /// as a function value at the moment. public func greater(x : Nat8, y : Nat8) : Bool { x > y }; - /// Returns `x >= y`. + /// "Greater than or equal" function for Nat8 types. + /// This is equivalent to `x >= y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.greaterOrEqual(2, 1); // => true + /// (2 : Nat8) >= (1 : Nat8) // => true + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>=` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>=` + /// as a function value at the moment. public func greaterOrEqual(x : Nat8, y : Nat8) : Bool { x >= y }; - /// Returns the order of `x` and `y`. + /// General purpose comparison function for `Nat8`. Returns the `Order` ( + /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.compare(2, 3) // => #less + /// ``` + /// + /// This function can be used as value for a high order function, such as a sort function. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.sort([2, 3, 1] : [Nat8], Nat8.compare) // => [1, 2, 3] + /// ``` public func compare(x : Nat8, y : Nat8) : { #less; #equal; #greater } { if (x < y) { #less } else if (x == y) { #equal } else { #greater } }; - /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow. + /// Returns the sum of `x` and `y`, `x + y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.add(1, 2); // => 3 + /// (1 : Nat8) + (2 : Nat8) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 0, Nat8.add) // => 6 + /// ``` public func add(x : Nat8, y : Nat8) : Nat8 { x + y }; - /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow. + /// Returns the difference of `x` and `y`, `x - y`. + /// Traps on underflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.sub(2, 1); // => 1 + /// (2 : Nat8) - (1 : Nat8) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 20, Nat8.sub) // => 14 + /// ``` public func sub(x : Nat8, y : Nat8) : Nat8 { x - y }; - /// Returns the product of `x` and `y`, `x * y`. Traps on overflow. + /// Returns the product of `x` and `y`, `x * y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.mul(2, 3); // => 6 + /// (2 : Nat8) * (3 : Nat8) // => 6 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*` + /// as a function value at the moment. + /// + /// Example: + /// ```motoko include=import + /// import Array "mo:base/Array"; + /// Array.foldLeft([2, 3, 1], 1, Nat8.mul) // => 6 + /// ``` public func mul(x : Nat8, y : Nat8) : Nat8 { x * y }; - /// Returns the division of `x by y`, `x / y`. + /// Returns the quotient of `x` divided by `y`, `x / y`. /// Traps when `y` is zero. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.div(6, 2); // => 3 + /// (6 : Nat8) / (2 : Nat8) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `/` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `/` + /// as a function value at the moment. public func div(x : Nat8, y : Nat8) : Nat8 { x / y }; /// Returns the remainder of `x` divided by `y`, `x % y`. /// Traps when `y` is zero. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.rem(6, 4); // => 2 + /// (6 : Nat8) % (4 : Nat8) // => 2 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `%` + /// as a function value at the moment. public func rem(x : Nat8, y : Nat8) : Nat8 { x % y }; - /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow. + /// Returns `x` to the power of `y`, `x ** y`. + /// Traps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.pow(2, 3); // => 8 + /// (2 : Nat8) ** (3 : Nat8) // => 8 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**` + /// as a function value at the moment. public func pow(x : Nat8, y : Nat8) : Nat8 { x ** y }; /// Returns the bitwise negation of `x`, `^x`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.bitnot(0); // => 255 + /// ^(0 : Nat8) // => 255 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitnot(x : Nat8) : Nat8 { ^x }; /// Returns the bitwise and of `x` and `y`, `x & y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.bitand(3, 2); // => 2 + /// (3 : Nat8) & (2 : Nat8) // => 2 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `&` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `&` + /// as a function value at the moment. public func bitand(x : Nat8, y : Nat8) : Nat8 { x & y }; - /// Returns the bitwise or of `x` and `y`, `x \| y`. + /// Returns the bitwise or of `x` and `y`, `x | y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.bitor(3, 2); // => 3 + /// (3 : Nat8) | (2 : Nat8) // => 3 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `|` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `|` + /// as a function value at the moment. public func bitor(x : Nat8, y : Nat8) : Nat8 { x | y }; /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.bitxor(3, 2); // => 1 + /// (3 : Nat8) ^ (2 : Nat8) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `^` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `^` + /// as a function value at the moment. public func bitxor(x : Nat8, y : Nat8) : Nat8 { x ^ y }; /// Returns the bitwise shift left of `x` by `y`, `x << y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.bitshiftLeft(1, 2); // => 4 + /// (1 : Nat8) << (2 : Nat8) // => 4 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<` + /// as a function value at the moment. public func bitshiftLeft(x : Nat8, y : Nat8) : Nat8 { x << y }; /// Returns the bitwise shift right of `x` by `y`, `x >> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.bitshiftRight(4, 2); // => 1 + /// (4 : Nat8) >> (2 : Nat8) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `>>` + /// as a function value at the moment. public func bitshiftRight(x : Nat8, y : Nat8) : Nat8 { x >> y }; /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.bitrotLeft(128, 1); // => 1 + /// (128 : Nat8) <<> (1 : Nat8) // => 1 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<<>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<<>` + /// as a function value at the moment. public func bitrotLeft(x : Nat8, y : Nat8) : Nat8 { x <<> y }; /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.bitrotRight(1, 1); // => 128 + /// (1 : Nat8) <>> (1 : Nat8) // => 128 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `<>>` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `<>>` + /// as a function value at the moment. public func bitrotRight(x : Nat8, y : Nat8) : Nat8 { x <>> y }; /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`. + /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing. + /// + /// Example: + /// ```motoko include=import + /// Nat8.bittest(5, 2); // => true + /// ``` public func bittest(x : Nat8, p : Nat) : Bool { Prim.btstNat8(x, Prim.natToNat8(p)) }; /// Returns the value of setting bit `p mod 8` in `x` to `1`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.bitset(5, 1); // => 7 + /// ``` public func bitset(x : Nat8, p : Nat) : Nat8 { x | (1 << Prim.natToNat8(p)) }; /// Returns the value of clearing bit `p mod 8` in `x` to `0`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.bitclear(5, 2); // => 1 + /// ``` public func bitclear(x : Nat8, p : Nat) : Nat8 { x & ^(1 << Prim.natToNat8(p)) }; /// Returns the value of flipping bit `p mod 8` in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.bitflip(5, 2); // => 1 + /// ``` public func bitflip(x : Nat8, p : Nat) : Nat8 { x ^ (1 << Prim.natToNat8(p)) }; /// Returns the count of non-zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.bitcountNonZero(5); // => 2 + /// ``` public let bitcountNonZero : (x : Nat8) -> Nat8 = Prim.popcntNat8; /// Returns the count of leading zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.bitcountLeadingZero(5); // => 5 + /// ``` public let bitcountLeadingZero : (x : Nat8) -> Nat8 = Prim.clzNat8; /// Returns the count of trailing zero bits in `x`. + /// + /// Example: + /// ```motoko include=import + /// Nat8.bitcountTrailingZero(6); // => 1 + /// ``` public let bitcountTrailingZero : (x : Nat8) -> Nat8 = Prim.ctzNat8; /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.addWrap(230, 26); // => 0 + /// (230 : Nat8) +% (26 : Nat8) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `+%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `+%` + /// as a function value at the moment. public func addWrap(x : Nat8, y : Nat8) : Nat8 { x +% y }; /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.subWrap(0, 1); // => 255 + /// (0 : Nat8) -% (1 : Nat8) // => 255 + /// ``` + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `-%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `-%` + /// as a function value at the moment. public func subWrap(x : Nat8, y : Nat8) : Nat8 { x -% y }; /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.mulWrap(230, 26); // => 92 + /// (230 : Nat8) *% (26 : Nat8) // => 92 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `*%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `*%` + /// as a function value at the moment. public func mulWrap(x : Nat8, y : Nat8) : Nat8 { x *% y }; /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. + /// + /// Example: + /// ```motoko include=import + /// ignore Nat8.powWrap(2, 8); // => 0 + /// (2 : Nat8) **% (8 : Nat8) // => 0 + /// ``` + /// + /// Note: The reason why this function is defined in this library (in addition + /// to the existing `**%` operator) is so that you can use it as a function + /// value to pass to a higher order function. It is not possible to use `**%` + /// as a function value at the moment. public func powWrap(x : Nat8, y : Nat8) : Nat8 { x **% y }; }