---
title: Math
description: "Various math helper functions from the Core library of Tact"
---

import { Badge } from '@astrojs/starlight/components';

Various math helper functions.

## min

```tact
fun min(x: Int, y: Int): Int;
```

Computes and returns the [minimum](https://en.wikipedia.org/wiki/Maximum_and_minimum) of two [`Int{:tact}`][int] values `x` and `y`.

Usage examples:

```tact
min(1, 2);        // 1
min(2, 2);        // 2
min(007, 3);      // 3
min(0x45, 3_0_0); // 69, nice
//  ↑     ↑
//  69    300
```

## max

```tact
fun max(x: Int, y: Int): Int;
```

Computes and returns the [maximum](https://en.wikipedia.org/wiki/Maximum_and_minimum) of two [`Int{:tact}`][int] values `x` and `y`.

Usage examples:

```tact
max(1, 2);        // 2
max(2, 2);        // 2
max(007, 3);      // 7
max(0x45, 3_0_0); // 300
//  ↑     ↑
//  69    300
```

## abs

```tact
fun abs(x: Int): Int;
```

Computes and returns the [absolute value](https://en.wikipedia.org/wiki/Absolute_value) of the [`Int{:tact}`][int] value `x`.

Usage examples:

```tact
abs(42);        // 42
abs(-42);       // 42
abs(-(-(-42))); // 42
```

## sign

<Badge text="Available since Tact 1.6" variant="tip" size="medium"/><p/>

```tact
fun sign(x: Int): Int;
```

Computes and returns the sign of the [`Int{:tact}`][int] value `x`. Produces $1$ if `x` is positive, $-1$ if `x` is negative, and $0$ if `x` is $0$.

Usage examples:

```tact
sign(42);        // 1
sign(-42);       // -1
sign(-(-42));    // 1
sign(-(-(-42))); // -1
sign(0);         // 0
```

## sqrt

<Badge text="500+ gas" title="Uses 500 gas units or more" variant="danger" size="medium"/>
<Badge text="Available since Tact 1.6" variant="tip" size="medium"/><p/>

```tact
fun sqrt(num: Int): Int;
```

Computes the [square root](https://en.wikipedia.org/wiki/Square_root) of the [`Int{:tact}`][int] value `num`. Returns the result rounded to the nearest integer. If there are two equally close integers, rounding is done toward the even one.

Attempts to specify a negative value for `num` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.

Usage examples:

```tact
sqrt(4);  // 2
sqrt(3);  // 2
sqrt(2);  // 1
sqrt(1);  // 1
sqrt(0);  // 0
sqrt(-1); // ERROR! Exit code 5: Integer out of expected range
```

## divc

<Badge text="Available since Tact 1.6" variant="tip" size="medium"/><p/>

```tact
fun divc(x: Int, y: Int): Int;
```

Computes and returns the [rounded up][round-up] result of division of the [`Int{:tact}`][int] `x` by the [`Int{:tact}`][int] `y`.

Attempts to divide by `y` equal to $0$ throw an exception with [exit code 4](/book/exit-codes#4): `Integer overflow`.

Usage examples:

```tact
divc(4, 2);  // 2
divc(3, 2);  // 2
divc(-4, 2); // -2
divc(-3, 2); // -1
```

## muldivc

<Badge text="Available since Tact 1.6" variant="tip" size="medium"/><p/>

```tact
fun muldivc(x: Int, y: Int, z: Int): Int;
```

Computes and returns the [rounded up][round-up] result of `(x * y) / z{:tact}`.

If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, or if there is an attempt to divide by `z` equal to $0$, an exception with [exit code 4](/book/exit-codes#4) is thrown: `Integer overflow`.

Usage examples:

```tact
muldivc(4, 1, 2);  // 2
muldivc(3, 1, 2);  // 2
muldivc(-4, 1, 2); // -2
muldivc(-3, 1, 2); // -1
muldivc(-3, 0, 2); // 0
muldivc(-3, 0, 0); // ERROR! Exit code 4: Integer overflow
```

## mulShiftRight

<Badge text="Available since Tact 1.6" variant="tip" size="medium"/><p/>

```tact
fun mulShiftRight(x: Int, y: Int, z: Int): Int;
```

Computes and returns the [rounded down][round-down] result of `(x * y) / 2^z{:tact}`. It is a more gas-efficient equivalent of performing the [bitwise shift right](/book/operators#binary-bitwise-shift-right) on the result of multiplication of [`Int{:tact}`][int] `x` by [`Int{:tact}`][int] `y`, where [`Int{:tact}`][int] `z` is the right operand of the shift.

If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, an exception with [exit code 4](/book/exit-codes#4) is thrown: `Integer overflow`.

Attempts to specify any value of `z` outside the inclusive range from $0$ to $256$ throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.

Usage examples:

```tact
mulShiftRight(5, 5, 2);  // 6
mulShiftRight(5, 5, 1);  // 12
mulShiftRight(5, 5, 0);  // 25
mulShiftRight(5, 5, -1); // ERROR! Exit code 5: Integer out of expected range
```

## mulShiftRightRound

<Badge text="Available since Tact 1.6" variant="tip" size="medium"/><p/>

```tact
fun mulShiftRightRound(x: Int, y: Int, z: Int): Int;
```

Similar to [`mulShiftRight(){:tact}`](#mulshiftright), but instead of [rounding down][round-down], the result value is rounded to the nearest integer. If there are two equally close integers, rounding is done toward the even one.

If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, an exception with [exit code 4](/book/exit-codes#4) is thrown: `Integer overflow`.

Attempts to specify any value of `z` outside the inclusive range from $0$ to $256$ throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.

Usage examples:

```tact
mulShiftRightRound(5, 5, 2);  // 6
mulShiftRightRound(5, 5, 1);  // 13
mulShiftRightRound(5, 5, 0);  // 25
mulShiftRightRound(5, 5, -1); // ERROR! Exit code 5: Integer out of expected range
```

## mulShiftRightCeil

<Badge text="Available since Tact 1.6" variant="tip" size="medium"/><p/>

```tact
fun mulShiftRightCeil(x: Int, y: Int, z: Int): Int;
```

Similar to [`mulShiftRight(){:tact}`](#mulshiftright), but instead of [rounding down][round-down], the result value is [rounded up][round-up].

If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, an exception with [exit code 4](/book/exit-codes#4) is thrown: `Integer overflow`.

Attempts to specify any value of `z` outside the inclusive range from $0$ to $256$ throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.

Usage examples:

```tact
mulShiftRightCeil(5, 5, 2);  // 7
mulShiftRightCeil(5, 5, 1);  // 13
mulShiftRightCeil(5, 5, 0);  // 25
mulShiftRightCeil(5, 5, -1); // ERROR! Exit code 5: Integer out of expected range
```

## log

```tact
fun log(num: Int, base: Int): Int;
```

Computes and returns the [logarithm](https://en.wikipedia.org/wiki/Logarithm) of a number `num` $> 0$ to the base `base` $≥ 2$. Results are [rounded down][round-down].

Attempts to specify a non-positive `num` value or a `base` less than 2 throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.

Usage examples:

```tact
log(1000, 10); // 3, as 10^3 is 1000
//  ↑     ↑             ↑       ↑
//  num   base          base    num

log(1001, 10);  // 3
log(999, 10);   // 2
try {
    log(-1000, 10); // exit code 5 because of the non-positive num
}
log(1024, 2);   // 10
try {
    log(1024, -2);  // exit code 5 because the base is less than 1
}
```

:::note

  If you only need to obtain logarithms to the base 2, use the [`log2(){:tact}`](#log2) function, as it's more gas-efficient.

:::

## log2

```tact
fun log2(num: Int): Int;
```

Similar to [`log(){:tact}`](#log), but sets the `base` to 2.

Attempts to specify a non-positive `num` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.

Usage example:

```tact
log2(1024); // 10, as 2^10 is 1024
//   ↑                ↑       ↑
//   num              base₂   num
```

:::note

  In order to reduce gas usage, prefer using this function over calling [`log(){:tact}`](#log) when you only need to obtain logarithms to the base 2.

:::

## pow

```tact
fun pow(base: Int, exp: Int): Int;
```

Computes and returns the [exponentiation](https://en.wikipedia.org/wiki/Exponentiation) involving two numbers: the `base` and the exponent (or _power_) `exp`. Exponent `exp` must be non-negative; otherwise, an exception with [exit code 5](/book/exit-codes#5) is thrown: `Integer out of expected range`.

This function tries to resolve constant values at [compile-time](/ref/core-comptime) whenever possible.

Usage examples:

```tact
contract Example {
    // Persistent state variables
    p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8
    one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1
                          // works at compile-time!

    // Internal message receiver
    receive() {
        pow(self.p23, self.one + 1); // 64, works at run-time too!
        try {
            pow(0, -1); // exit code 5: Integer out of expected range
        }
    }
}
```

:::note

  If you only need to obtain powers of $2$, use the [`pow2(){:tact}`](#pow2) function, as it's more gas-efficient.

:::

:::note

  List of functions that only work at compile-time: [API Comptime](/ref/core-comptime).

:::

## pow2

```tact
fun pow2(exp: Int): Int;
```

Similar to [`pow(){:tact}`](#pow), but sets the `base` to $2$. The exponent `exp` must be non-negative; otherwise, an error with [exit code 5](/book/exit-codes#5) will be thrown: `Integer out of expected range`.

This function tries to resolve constant values at [compile-time](/ref/core-comptime) whenever possible.

Usage examples:

```tact
contract Example {
    // Persistent state variables
    p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8
    one: Int = pow2(0); // raises 2 to the power 0, which always produces 1
                        // works at compile-time!

    // Internal message receiver, which accepts message ExtMsg
    receive() {
        pow2(self.one + 1); // 4, works at run-time too!
        try {
            pow(-1); // exit code 5: Integer out of expected range
        }
    }
}
```

:::note

  In order to reduce gas usage, prefer using this function over calling [`pow(){:tact}`](#pow) when you only need to obtain powers of $2$.

:::

:::note

  List of functions that only work at compile-time: [API Comptime](/ref/core-comptime).

:::

[p]: /book/types#primitive-types
[int]: /book/integers

[round-up]: https://en.wikipedia.org/wiki/Rounding#Rounding_up
[round-down]: https://en.wikipedia.org/wiki/Rounding#Rounding_down
