Integers and mutez ​

SmartPy has several types for integers: `sp.nat` for non-negative integers, `sp.int` for (all) integers, and `sp.mutez` for non-negative amounts of micro-Tez, the token of the Tezos blockchain.

`sp.int` and `sp.nat`​

A literal integer such as `2` is either of type `sp.nat` or `sp.int`, depending on how it is used. In order to be explicit about the type, you can simply write `sp.nat(2)` or `sp.int(2)`.

Basic arithmetic ​

The operators `+`, `-`, `*` and `/` perform addition, subtraction, multiplication, and division, respectively. They are homogeneous, meaning that both arguments must be of the same type (either both `sp.nat` or both `sp.int`).

The type of the result is the same as the arguments, except for `-`, which always returns an `sp.int`.

Examples:

smartpy
``````assert sp.nat(2) + sp.nat(3) == sp.nat(5)
assert sp.int(2) + sp.int(3) == sp.int(5)
assert sp.nat(2) - sp.nat(3) == sp.int(-1)
assert sp.int(2) - sp.int(3) == sp.int(-1)
``````

The unary negation operator `-` can take either `sp.nat` or `sp.int` and always returns an `sp.int`. For example, `- sp.nat(2) == sp.int(-2)`.

Mixing different types yields an error: for example `sp.nat(2) + sp.int(3)` is invalid. For heterogeneous arguments there are `sp.add`, `sp.sub`, `sp.mul`.

Example:

smartpy
``````a = sp.nat(2)
b = sp.int(3)
``````

Division ​

`sp.ediv` performs Euclidean division. If both of its arguments are of type `sp.nat`, its result type is `sp.option[sp.pair[sp.nat, sp.nat]]`, otherwise `sp.option[sp.pair[sp.int, sp.nat]]`.

The option catches division by zero: `sp.ediv(a, 0) == None`. If `b != 0`, then `sp.ediv(a, b) = sp.Some(q, r)` where `q` (the quotient) and `r` (the remainder) are the unique integers such that `a == q * b + r` and both `0 <= r` and `r < b`.

Example:

smartpy
``````assert sp.ediv( 14, 3) == sp.Some(( 4, 2))  #  14 ==  4 *  3 + 2
assert sp.ediv(-14, 3) == sp.Some((-5, 1))  # -14 == -5 *  3 + 1
assert sp.ediv( 14,-3) == sp.Some((-4, 2))  #  14 == -4 * -3 + 2
assert sp.ediv(-14,-3) == sp.Some(( 5, 1))  # -14 ==  5 * -3 + 1
``````

If `a` and `b` are of the same type quotient and remainder can be obtained as `a / b` and `sp.mod(a, b)`, respectively. In both cases a `Division_by_zero` error is raised if `b == 0`.

WARNING

For negative denominators the result of division differs between SmartPy and Python. SmartPy follows the Michelson semantics, whereas Python rounds the quotient towards negative infinity (yielding negative remainders!). To avoid confusion between the two, the SmartPy syntax uses `/` and `sp.mod` instead of `//` and `%`.

Comparison ​

Two integers of the same type (either `sp.nat` or `sp.int`) can be compared with the operators `==`, `!=`, `<`, `<=`, `>`, `>=`. The result is of type `sp.bool`. For example, `2 == 3` is `False`.

From `sp.nat` to `sp.int`​

To convert from `sp.nat` to `sp.int`, there is `sp.to_int`. For example `sp.to_int(sp.nat(2)) == sp.to_int(2)`, or (thanks to type inference) `sp.to_int(2) == 2`.

From `sp.int` to `sp.nat`​

`sp.is_nat` takes an `sp.int` and returns a value of type `sp.option[sp.nat]`. If `a >= 0`, then `sp.is_nat(a) == sp.Some(b)`, where `b` is the unique `sp.nat` such that `sp.to_int(b) == a` (i.e. `a` and `b` represent the same integer). If `a < 0`, then `sp.is_nat(a) == None`. For example:

smartpy
``````assert sp.is_nat( 2) == sp.Some(2)
assert sp.is_nat(-2) == None
``````

`sp.as_nat` performs the same conversion, but instead of returning an option raises an error on negative numbers. Thus `sp.as_nat(2) == 2`, whereas `sp.as_nat(-2)` yields an error.

Bitwise arithmetic ​

Bitwise and and or operations are available as `|` and `&` on `sp.nat`:

smartpy
``````assert 42 & 1 == 0
assert 42 | 1 == 43
``````

Token amounts ​

Micro-Tez amounts are always prefixed by `sp.mutez`, so e.g. `sp.mutez(42)` denotes 42 micro-Tez, e.g. `0.000042` Tez. This expression is of type `sp.mutez`.

`sp.tez(a)` is equivalent to `sp.mutez(a * 1_000_000)`.

Addition and subtraction on `sp.mutez` can be performed with `+` and `-`. If subtraction were to yield a negative value, an error is raised instead. Thus `sp.mutez(5) - sp.mutez(2) == sp.mutez(3)`, whereas `sp.mutez(5) - sp.mutez(10)` yields an error.

smartpy
``````sp.split_tokens(amount: sp.mutez, quantity: sp.nat, division: sp.nat)
-> sp.mutez
``````

For combined multiplication and division on `sp.mutez` values there is `sp.split_tokens(a, b, c)`, which calculates the value "`a * b / c`".

This enables the computation of mutez percentages, for example:

smartpy
``````sp.split_tokens(sp.mutez(200), 5, 100) == sp.mutez(10)  # 5% of 200 mutez
``````