# Math

The Cairo common library has modules for some common operations.

The following are available:

- Not zero:
`assert_not_zero(val)`

. Asserts that`val`

is not zero.

- Not equal:
`assert_not_equal(a, b)`

. Asserts that`a`

is not equal to`b`

.

- Not negative:
`assert_nn(val)`

. Asserts that`val`

is not negative.

- Less than or equal to:
`assert_le(a, b)`

. Asserts that`a`

is less than or equal to`b`

.

- Less than:
`assert_lt(a, b)`

. Asserts that`a`

is less than`b`

.

- Not negative and less than or equal to:
`assert_nn_le()`

. Asserts that`a`

is both not negative and less than or equal to`b`

.

- In range:
`assert_in_range(val, a, b)`

. Asserts that`val`

is both greater than or equal to`a`

, and less than`b`

.

- 250-bit:
`assert_250_bit(val)`

. Asserts that`val`

is smaller then the maximum value in 250-bit space.

- Split felt:
`split_felt(val)`

. Returns`high`

and`low`

parts of`val`

.- See integer lifts.

- Less than or equal to (with split felt):
`assert_le_felt(a, b)`

. Asserts that`a`

is less than or equal to`b`

using split felt method.- See integer lifts

- Less than (with split felt):
`assert_lt_felt(a, b)`

. Asserts that`a`

is less than`b`

using split felt method.- See integer lifts

- Absolute value:
`abs_value(val)`

. Returns`val`

as a positive value.

- Sign:
`sign(val)`

. Returns one of`-1`

,`0`

or`1`

for a`val`

that is negative, zero or positive respectively.

- Unsigned division remainder:
`unsigned_div_rem(value, div)`

. Returns the quotient`q`

and remainder`r`

from integer division of`value/div`

as positive values.

- Signed division remainder:
`signed_div_rem(value, div)`

. Returns the quotient`q`

and remainder`r`

from integer division of`value/div`

, with quotient sign either positive or negative.- Handles integer and modulo operations with negative numbers the same way Python does, where
`-100 // 3`

returns`-34`

and`-100 % 3`

returns`2`

.

```
%lang starknet
%builtins pedersen range_check
from starkware.cairo.common.math import (
assert_not_zero, assert_not_equal, assert_nn, assert_le, assert_lt, assert_nn_le, assert_in_range, assert_250_bit, split_felt, assert_le_felt, assert_lt_felt, abs_value, sign, unsigned_div_rem, signed_div_rem)
# Accepts two numbers for integer division (signed, unsigned).
# Demonstrates successful cases of math operations.
@view
func check_values{range_check_ptr}(
num_1: felt, num_2: felt) -> (
u_quot: felt, u_rem: felt, s_quot: felt, s_rem: felt):
alloc_locals
assert_not_zero(100)
assert_not_zero(-100)
# assert_not_zero(0) # Fails.
assert_not_equal(100, 150)
# assert_not_equal(100, 100) # Fails.
assert_nn(100)
assert_nn(0)
# assert_nn(0) # Fails.
assert_le(100, 150)
assert_le(100, 100)
# assert_le(100, 50) # Fails.
assert_lt(100, 150)
# assert_lt(100, 100) # Fails.
# assert_lt(100, 150) # Fails.
assert_nn_le(100, 150)
# assert_nn_le(-100, 150) # Fails.
# assert_nn_le(100, 50) # Fails.
assert_in_range(150, 100, 200)
assert_in_range(150, -100, 200)
# assert_in_range(50, 100, 200) # Fails.
assert_250_bit(9234)
assert_250_bit(2**250 - 1)
# assert_250_bit(2**250) # Fails.
# assert_250_bit(-100) # Fails.
let (high_1, low_1) = split_felt(100 * 2**128 + 150)
assert high_1 = 100 # Just crosses mid-point (128 bits)
assert low_1 = 150
let (high_2, low_2) = split_felt(100 * 2**130 + 150)
assert high_2 = 100 * 2 ** 2 # A bit more than high_1
assert low_2 = 150
assert_le_felt(150, 200)
assert_le_felt(150, 150)
# assert_le_felt(150, 50) # Fails.
assert_lt_felt(150, 200)
# assert_lt_felt(150, 150) Fails.
# assert_lt_felt(150, 50) Fails.
let (local a) = abs_value(-150)
assert a = 150
let (local b) = sign(0)
assert b = 0
let (local c) = sign(-50)
assert c = -1
let (local d, e) = unsigned_div_rem(100, 3)
assert d = 33
assert e = 1
let (local u_quot, u_rem) = unsigned_div_rem(num_1, num_2)
# This check must be less than 2 ** 64
let RANGE_CHECK_BOUND = 2 ** 20
let (local f, g) = signed_div_rem(-100, 3, RANGE_CHECK_BOUND)
# To have these asserts pass, the -1 and +1 have been added to
# the expected values.
assert f = -34
assert g = 3
let (local s_quot, s_rem) = signed_div_rem(-num_1, num_2,
RANGE_CHECK_BOUND)
return (u_quot, u_rem, s_quot, s_rem)
end
```

Save as `math.cairo`

.

### Compile

Then, to compile:

```
starknet-compile math.cairo \
--output math_compiled.json \
--abi math_contract_abi.json
```

### Deploy

Then, to deploy:

```
starknet deploy --contract math_compiled.json \
--network=alpha
Returns:
Deploy transaction was sent.
Contract address: 0x069c755d08c37685d6a1705277c59567fe1f764d009354d8987ea49d134dcc73
Transaction ID: 169365
```

*Note:* Remove the zero after the `x`

, 0x[0]12345. E.g., 0x0123abc becomes 0x123abc.

### Monitor

Check the status of the transaction:

```
starknet tx_status --network=alpha --id=169365
Returns:
{
"block_id": 38624
"tx_status": "PENDING"
}
```

### Interact

Then, to interact supply a divisor and remainder (1000, 501):

```
starknet call \
--network=alpha \
--address 0x69c755d08c37685d6a1705277c59567fe1f764d009354d8987ea49d134dcc73 \
--abi math_contract_abi.json \
--function check_values \
--inputs 1000 501
Returns:
1 499 3618502788666131213697322783095070105623107215331596699973092056135872020479 2
```

Recall that the prime used for Cairo is:

```
>>> prime = 2**251 + 17 * 2**192 + 1`
>>> prime
3618502788666131213697322783095070105623107215331596699973092056135872020481
```

So the result (`...0479`

) is two less than the largest number (`...0481`

),
it is therefore equivalent to `-2`

.

So the result for signed_div_rem(-1000, 501) is (-2, 2), which matches the Python equivalent:

```
>>> -1000 // 501
-2
>>> -1000 % 501
2
```

Status options:

- NOT_RECEIVED: The transaction has not been received yet (i.e., not written to storage).
- RECEIVED: The transaction was received by the operator.
- PENDING: The transaction passed the validation and is waiting to be sent on-chain.
- REJECTED: The transaction failed validation and thus was skipped.
- ACCEPTED_ONCHAIN: The transaction was accepted on-chain.

- PENDING: The transaction passed the validation and is waiting to be sent on-chain.

Visit the voyager explorer to see the transactions.