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;
// ...