Skip to main content

core/Nat

Natural numbers with infinite precision.

Most operations on natural numbers (e.g. addition) are available as built-in operators (e.g. 1 + 1). This module provides equivalent functions and Text conversion.

Import from the core library to use this module.

import Nat "mo:core/Nat";

Type Nat​

type Nat = Prim.Types.Nat

Infinite precision natural numbers.

Function toText​

func toText(n : Nat) : Text

Converts a natural number to its textual representation. Textual representation do not contain underscores to represent commas.

Example:

assert Nat.toText(1234) == "1234";

Function fromText​

func fromText(text : Text) : ?Nat

Creates a natural number from its textual representation. Returns null if the input is not a valid natural number.

The textual representation must not contain underscores.

Example:

assert Nat.fromText("1234") == ?1234;

Function fromInt​

func fromInt(int : Int) : Nat

Converts an integer to a natural number. Traps if the integer is negative.

Example:

assert Nat.fromInt(1234) == (1234 : Nat);

Function toInt​

func toInt(nat : Nat) : Int

Converts a natural number to an integer.

Example:

assert Nat.toInt(1234) == 1234;

Function min​

func min(x : Nat, y : Nat) : Nat

Returns the minimum of x and y.

Example:

assert Nat.min(1, 2) == 1;

Function max​

func max(x : Nat, y : Nat) : Nat

Returns the maximum of x and y.

Example:

assert Nat.max(1, 2) == 2;

Function equal​

func equal(x : Nat, y : Nat) : Bool

Equality function for Nat types. This is equivalent to x == y.

Example:

assert Nat.equal(1, 1);
assert 1 == 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:

let a = 111;
let b = 222;
assert not Nat.equal(a, b);

Function notEqual​

func notEqual(x : Nat, y : Nat) : Bool

Inequality function for Nat types. This is equivalent to x != y.

Example:

assert Nat.notEqual(1, 2);
assert 1 != 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.

Function less​

func less(x : Nat, y : Nat) : Bool

"Less than" function for Nat types. This is equivalent to x < y.

Example:

assert Nat.less(1, 2);
assert 1 < 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.

Function lessOrEqual​

func lessOrEqual(x : Nat, y : Nat) : Bool

"Less than or equal" function for Nat types. This is equivalent to x <= y.

Example:

assert Nat.lessOrEqual(1, 2);
assert 1 <= 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.

Function greater​

func greater(x : Nat, y : Nat) : Bool

"Greater than" function for Nat types. This is equivalent to x > y.

Example:

assert Nat.greater(2, 1);
assert 2 > 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.

Function greaterOrEqual​

func greaterOrEqual(x : Nat, y : Nat) : Bool

"Greater than or equal" function for Nat types. This is equivalent to x >= y.

Example:

assert Nat.greaterOrEqual(2, 1);
assert 2 >= 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.

Function compare​

func compare(x : Nat, y : Nat) : Order.Order

General purpose comparison function for Nat. Returns the Order ( either #less, #equal, or #greater) of comparing x with y.

Example:

assert Nat.compare(2, 3) == #less;

This function can be used as value for a high order function, such as a sort function.

Example:

import Array "mo:core/Array";
assert Array.sort([2, 3, 1], Nat.compare) == [1, 2, 3];

Function add​

func add(x : Nat, y : Nat) : Nat

Returns the sum of x and y, x + y. This operator will never overflow because Nat is infinite precision.

Example:

assert Nat.add(1, 2) == 3;
assert 1 + 2 == 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:

import Array "mo:core/Array";
assert Array.foldLeft([2, 3, 1], 0, Nat.add) == 6;

Function sub​

func sub(x : Nat, y : Nat) : Nat

Returns the difference of x and y, x - y. Traps on underflow below 0.

Example:

assert Nat.sub(2, 1) == 1;
// Add a type annotation to avoid a warning about the subtraction
assert 2 - 1 : Nat == 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:

import Array "mo:core/Array";
assert Array.foldLeft([2, 3, 1], 10, Nat.sub) == 4;

Function mul​

func mul(x : Nat, y : Nat) : Nat

Returns the product of x and y, x * y. This operator will never overflow because Nat is infinite precision.

Example:

assert Nat.mul(2, 3) == 6;
assert 2 * 3 == 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:

import Array "mo:core/Array";
assert Array.foldLeft([2, 3, 1], 1, Nat.mul) == 6;

Function div​

func div(x : Nat, y : Nat) : Nat

Returns the unsigned integer division of x by y, x / y. Traps when y is zero.

The quotient is rounded down, which is equivalent to truncating the decimal places of the quotient.

Example:

assert Nat.div(6, 2) == 3;
assert 6 / 2 == 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.

Function rem​

func rem(x : Nat, y : Nat) : Nat

Returns the remainder of unsigned integer division of x by y, x % y. Traps when y is zero.

Example:

assert Nat.rem(6, 4) == 2;
assert 6 % 4 == 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.

Function pow​

func pow(x : Nat, y : Nat) : Nat

Returns x to the power of y, x ** y. Traps when y > 2^32. This operator will never overflow because Nat is infinite precision.

Example:

assert Nat.pow(2, 3) == 8;
assert 2 ** 3 == 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.

Function bitshiftLeft​

func bitshiftLeft(x : Nat, y : Nat32) : Nat

Returns the (conceptual) bitwise shift left of x by y, x * (2 ** y).

Example:

assert Nat.bitshiftLeft(1, 3) == 8;

Note: The reason why this function is defined in this library (in absence of the << operator) is so that you can use it as a function value to pass to a higher order function. While Nat is not defined in terms of bit patterns, conceptually it can be regarded as such, and the operation is provided as a high-performance version of the corresponding arithmetic rule.

Function bitshiftRight​

func bitshiftRight(x : Nat, y : Nat32) : Nat

Returns the (conceptual) bitwise shift right of x by y, x / (2 ** y).

Example:

assert Nat.bitshiftRight(8, 3) == 1;

Note: The reason why this function is defined in this library (in absence of the >> operator) is so that you can use it as a function value to pass to a higher order function. While Nat is not defined in terms of bit patterns, conceptually it can be regarded as such, and the operation is provided as a high-performance version of the corresponding arithmetic rule.

Function range​

func range(fromInclusive : Nat, toExclusive : Nat) : Iter.Iter<Nat>

Returns an iterator over Nat values from the first to second argument with an exclusive upper bound.

import Iter "mo:core/Iter";

let iter = Nat.range(1, 4);
assert iter.next() == ?1;
assert iter.next() == ?2;
assert iter.next() == ?3;
assert iter.next() == null;

If the first argument is greater than the second argument, the function returns an empty iterator.

import Iter "mo:core/Iter";

let iter = Nat.range(4, 1);
assert iter.next() == null; // empty iterator

Function rangeBy​

func rangeBy(fromInclusive : Nat, toExclusive : Nat, step : Int) : Iter.Iter<Nat>

Returns an iterator over Nat values from the first to second argument with an exclusive upper bound, incrementing by the specified step size. The step can be positive or negative.

import Iter "mo:core/Iter";

// Positive step
let iter1 = Nat.rangeBy(1, 7, 2);
assert iter1.next() == ?1;
assert iter1.next() == ?3;
assert iter1.next() == ?5;
assert iter1.next() == null;

// Negative step
let iter2 = Nat.rangeBy(7, 1, -2);
assert iter2.next() == ?7;
assert iter2.next() == ?5;
assert iter2.next() == ?3;
assert iter2.next() == null;

If step is 0 or if the iteration would not progress towards the bound, returns an empty iterator.

Function rangeInclusive​

func rangeInclusive(from : Nat, to : Nat) : Iter.Iter<Nat>

Returns an iterator over the integers from the first to second argument, inclusive.

import Iter "mo:core/Iter";

let iter = Nat.rangeInclusive(1, 3);
assert iter.next() == ?1;
assert iter.next() == ?2;
assert iter.next() == ?3;
assert iter.next() == null;

If the first argument is greater than the second argument, the function returns an empty iterator.

import Iter "mo:core/Iter";

let iter = Nat.rangeInclusive(3, 1);
assert iter.next() == null; // empty iterator

Function rangeByInclusive​

func rangeByInclusive(from : Nat, to : Nat, step : Int) : Iter.Iter<Nat>

Returns an iterator over the integers from the first to second argument, inclusive, incrementing by the specified step size. The step can be positive or negative.

import Iter "mo:core/Iter";

// Positive step
let iter1 = Nat.rangeByInclusive(1, 7, 2);
assert iter1.next() == ?1;
assert iter1.next() == ?3;
assert iter1.next() == ?5;
assert iter1.next() == ?7;
assert iter1.next() == null;

// Negative step
let iter2 = Nat.rangeByInclusive(7, 1, -2);
assert iter2.next() == ?7;
assert iter2.next() == ?5;
assert iter2.next() == ?3;
assert iter2.next() == ?1;
assert iter2.next() == null;

If from == to, return an iterator which only

Otherwise, if step is 0 or if the iteration would not progress towards the bound, returns an empty iterator.

Function allValues​

func allValues() : Iter.Iter<Nat>

Returns an infinite iterator over all possible Nat values.

import Iter "mo:core/Iter";

let iter = Nat.allValues();
assert iter.next() == ?0;
assert iter.next() == ?1;
assert iter.next() == ?2;
// ...