# Numbers

SmartPy has several types for integers:

`sp.nat`

for non-negative integers (zero and above), known as natural numbers or nats`sp.int`

for all integers`sp.mutez`

for non-negative amounts of micro-tez or mutez, which is one-millionth of a tez, the token of the Tezos blockchain

The types for integers and nats are not compatible with `sp.mutez`

, which means that you can't compare integers and nats with `sp.mutez`

types or use mathematical operations that combine them. However, you can use functions in the standard libraries to convert between nat and mutez.

SmartPy does not support floating-point numbers because Tezos does not.

## Integers and natural numbers

A literal integer such as 2 is either of type `sp.nat`

or `sp.int`

, depending on how it is used. To be explicit about the type, you can 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:

```
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, adding an integer to a nat is invalid, as in `sp.nat(2) + sp.int(3)`

.

To manipulate different types, SmartPy provides the functions `sp.add`

, `sp.sub`

, and `sp.mul`

, as in this example:

```
a = sp.nat(2)
b = sp.int(3)
assert sp.add(a, b) == sp.int(5)
```

### Division

- sp.ediv(a: sp.nat, b: sp.nat) → sp.option[sp.pair[sp.nat, sp.nat]]
- sp.ediv(a: sp.int, b: sp.nat) → sp.option[sp.pair[sp.int, sp.nat]]
- sp.ediv(a: sp.nat, b: sp.int) → sp.option[sp.pair[sp.int, sp.nat]]
- sp.ediv(a: sp.int, b: sp.int) → sp.option[sp.pair[sp.int, sp.nat]]
`sp.ediv`

performs Euclidean division, which returns the quotient and the remainder within an`sp.option`

type. Note that the quotient type depends on the types of the arguments.If both of the arguments are nats, the function returns an option with a nat for the quotient and a nat for the remainder, as in this example:

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

In any other combination of integers and nats,

`sp.ediv`

returns an option with an integer for the quotient and a nat for the remainder, as in these examples:smartpy`assert sp.ediv(sp.int(-14), sp.nat(3)) == sp.Some((sp.int(-5), sp.nat(1))) # -14 == -5 * 3 + 1 assert sp.ediv(sp.nat(14), sp.int(-3)) == sp.Some((sp.int(-4), sp.nat(2))) # 14 == -4 * -3 + 2 assert sp.ediv(sp.int(-14), sp.int(-3)) == sp.Some(( sp.int(5), sp.nat(1))) # -14 == 5 * -3 + 1`

If you try to divide by zero, the option type contains

`None`

, as in this example:smartpy`result_opt = sp.ediv(sp.nat(14), 0) with sp.match(result_opt): with sp.case.Some as result: (quotient, remainder) = result sp.trace(quotient) sp.trace(remainder) with None: sp.trace("Division by zero")`

If the option type contains

`Some`

, 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`

.

To get only the quotient or remainder of two integers or two nats, you can use `a / b`

and `sp.mod(a, b)`

, respectively. In either case, dividing by zero causes a `Division_by_zero`

.

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

You can compare two integers of the same type (either `sp.nat`

or `sp.int`

) with the operators `==`

, `!=`

, `<`

, `<=`

, `>`

, `>=`

. The result is of type `sp.bool`

. For example, `2 == 3`

is `False`

.

### Conversions

- sp.to_int(x: sp.nat) → sp.int
The function

`sp.to_int`

converts an`sp.nat`

to an`sp.int`

. For example`sp.to_int(sp.nat(2)) == sp.to_int(2)`

, or (thanks to type inference)`sp.to_int(2) == 2`

.

- sp.is_nat(a: sp.int) → sp.option[sp.nat]
The function

`sp.is_nat`

converts an`sp.int`

to an`sp.option[sp.nat]`

:- If a variable
`a`

is greater than or equal to zero,`sp.is_nat(a)`

returns`sp.Some(b)`

, where`sp.to_int(b) == a`

- If a variable
`a`

is less than zero,`sp.is_nat(a)`

returns`None`

For example:

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

- If a variable

- sp.as_nat(x: sp.int) → sp.nat
The function

`sp.as_nat`

performs the same conversion as`sp.is_nat`

, but instead of returning an option, it raises an error on negative numbers. Thus`sp.as_nat(2) == 2`

, whereas`sp.as_nat(-2)`

yields an error.

### Bitwise arithmetic

Bitwise *and*, *or* and *xor* operations are available as `&`

, `|`

and `^`

on `sp.nat`

:

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

Furthermore, `~x`

computes the two's complement of `x`

(of type `sp.int`

):

`assert ~100 == -101`

### Shifting

Left and right shifts are also available as `<<`

and `>>`

on `sp.nat`

:

```
assert 42 << 1 == 84
assert 42 >> 1 == 21
```

## Token amounts

The type `sp.mutez`

represents micro-tez, or one-millionth of one tez, so `sp.mutez(42)`

denotes 42 micro-tez or 0.000042 tez.

As shorthand, you can use `sp.tez()`

to create `sp.mutez`

types. For example, `sp.tez(a)`

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

.

You can add and subtract mutez values with the `+`

and `-`

operators but you cannot multiply them directly. Negative results raise errors. For example, `sp.mutez(5) - sp.mutez(2) == sp.mutez(3)`

, but `sp.mutez(5) - sp.mutez(10)`

raises an error.

- sp.split_tokens(amount: sp.mutez, quantity: sp.nat, division: sp.nat) → sp.mutez
The

`sp.split_tokens`

function helps multiply and divide tokens. It takes three`sp.mutez`

parameters and calculates the value`a * b / c`

. Its result is in`sp.mutez`

.This function enables the computation of mutez percentages. This example calculates 5% of 200 mutez:

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

This function rounds the result to the closest whole mutez or

`sp.mutez(0)`

if the result is closer to zero.