Integer Math API Reference
This page documents the public API of openzeppelin_math for OpenZeppelin Contracts for Sui v1.x.
use openzeppelin_math::rounding;Rounding strategy helpers shared by arithmetic operations across width-specific modules.
Types
Functions
Types
enum RoundingMode { Down, Up, Nearest }
enum
#Down always rounds toward zero, Up rounds toward ceiling, and Nearest rounds to the closest integer with ties rounded up.
Functions
down() -> RoundingMode
public
#Returns RoundingMode::Down.
up() -> RoundingMode
public
#Returns RoundingMode::Up.
nearest() -> RoundingMode
public
#Returns RoundingMode::Nearest (round-half-up behavior).
use openzeppelin_math::decimal_scaling;Helpers for converting balances between decimal precisions while enforcing safe casts and explicit truncation semantics.
Functions
safe_downcast_balance(raw_amount, source_decimals, target_decimals)safe_upcast_balance(amount, source_decimals, target_decimals)
Errors
Functions
safe_downcast_balance(raw_amount: u256, source_decimals: u8, target_decimals: u8) -> u64
public
#Converts a u256 amount to u64 across decimal domains. When scaling down (source_decimals > target_decimals), fractional residue is truncated, not rounded.
Aborts when decimals exceed 24 or when the scaled value cannot fit in u64.
safe_upcast_balance(amount: u64, source_decimals: u8, target_decimals: u8) -> u256
public
#Converts a u64 amount to u256 across decimal domains.
Scaling up preserves precision. Scaling down truncates fractional residue (no rounding). Aborts when decimal values exceed the supported range.
Errors
ESafeDowncastOverflowedInt (code 0)
error
#Raised when a downcast path would require representing a value larger than u64::MAX.
EInvalidDecimals (code 1)
error
#Raised when either decimal argument is greater than the package limit (24).
These modules expose a consistent API surface across unsigned widths.
Each module wraps shared arithmetic helpers with width-specific bit limits and representability checks.
Source modules:
Functions
average(a, b, rounding_mode)checked_shl(value, shift)checked_shr(value, shift)mul_div(a, b, denominator, rounding_mode)mul_shr(a, b, shift, rounding_mode)clz(value)msb(value)log2(value, rounding_mode)log256(value, rounding_mode)log10(value, rounding_mode)sqrt(value, rounding_mode)inv_mod(value, modulus)mul_mod(a, b, modulus)is_power_of_ten(n)
Functions
average(a: Int, b: Int, rounding_mode: RoundingMode) -> Int
public
#Returns the arithmetic mean of a and b for Int in {u8, u16, u32, u64, u128, u256}, rounded according to rounding_mode.
checked_shl(value: Int, shift: u8) -> Option<Int>
public
#Performs a lossless left shift. Returns none() when shifting would consume non-zero bits.
checked_shr(value: Int, shift: u8) -> Option<Int>
public
#Performs a lossless right shift. Returns none() when shifting would consume non-zero bits.
mul_div(a: Int, b: Int, denominator: Int, rounding_mode: RoundingMode) -> Option<Int>
public
#Computes (a * b) / denominator with configured rounding. Returns none() when the rounded value is not representable in the target width.
Aborts when denominator is zero.
mul_shr(a: Int, b: Int, shift: u8, rounding_mode: RoundingMode) -> Option<Int>
public
#Computes (a * b) >> shift with configured rounding and returns none() when the rounded result overflows the target width.
clz(value: Int) -> u8 | u16
public
#Counts leading zero bits. For u256, the return type is u16; for other widths it is u8.
msb(value: Int) -> u8
public
#Returns the zero-based index of the most significant set bit. By convention returns 0 for value = 0.
log2(value: Int, rounding_mode: RoundingMode) -> u8 | u16
public
#Computes base-2 logarithm with configured rounding. For u256, the return type is u16; for other widths it is u8.
log256(value: Int, rounding_mode: RoundingMode) -> u8
public
#Computes base-256 logarithm with configured rounding.
log10(value: Int, rounding_mode: RoundingMode) -> u8
public
#Computes base-10 logarithm with configured rounding.
sqrt(value: Int, rounding_mode: RoundingMode) -> Int
public
#Computes square root with configured rounding.
inv_mod(value: Int, modulus: Int) -> Option<Int>
public
#Computes modular multiplicative inverse.
Returns none() when inverse does not exist (including modulus = 1).
Aborts when modulus is zero.
mul_mod(a: Int, b: Int, modulus: Int) -> Int
public
#Computes (a * b) mod modulus.
Aborts when modulus is zero.
is_power_of_ten(n: Int) -> bool
public
#Returns true when n is a power of ten within the width's range. The check is implemented as a width-specific lookup table, so it is O(1) and never aborts.
use openzeppelin_math::u512;Wide-integer helper module used by high-precision arithmetic paths where u256 intermediates may overflow.
Types
Functions
new(hi, lo)zero()from_u256(value)hi(value)lo(value)ge(value, other)mul_u256(a, b)div_rem_u256(numerator, divisor)
Errors
Types
struct U512 { hi: u256, lo: u256 }
struct
#Represents a 512-bit unsigned integer as two u256 limbs.
Functions
new(hi: u256, lo: u256) -> U512
public
#Builds a U512 value from explicit high and low limbs.
zero() -> U512
public
#Returns the all-zero U512 value.
from_u256(value: u256) -> U512
public
#Embeds a u256 value as U512 { hi: 0, lo: value }.
hi(value: &U512) -> u256
public
#Returns the upper 256-bit limb.
lo(value: &U512) -> u256
public
#Returns the lower 256-bit limb.
ge(value: &U512, other: &U512) -> bool
public
#Lexicographic greater-or-equal comparison between two wide integers.
mul_u256(a: u256, b: u256) -> U512
public
#Computes full-width product a * b as a 512-bit result.
Aborts with ECarryOverflow if an internal carry invariant is violated.
div_rem_u256(numerator: U512, divisor: u256) -> (bool, u256, u256)
public
#Divides a 512-bit numerator by a non-zero u256 divisor.
Returns (overflow, quotient, remainder), where overflow = true indicates the exact quotient does not fit in u256.
In overflow cases, quotient is returned as 0 while remainder remains correct.
Errors
ECarryOverflow (code 0)
error
#Raised when cross-limb accumulation produces an out-of-range final carry.
EUnderflow (code 1)
error
#Raised when an internal borrow operation would underflow the high limb.
EDivideByZero (code 2)
error
#Raised when div_rem_u256 is called with divisor = 0.
EInvalidRemainder (code 3)
error
#Raised when internal division remainder invariants are violated.
use openzeppelin_math::vector;Vector algorithms for unsigned integers: generic in-place quicksort and median selection. The sorting macros use iterative quicksort with three-way partitioning (Dutch National Flag) and median-of-three pivot selection, backed by an explicit stack so they avoid Move macro recursion limits. Input size is still bounded by transaction gas and memory; avoid operating on unbounded, caller-controlled vectors.
Functions
quick_sort!(vec)quick_sort_by!(vec, le)median!(vec, rounding_mode)median_u8(vec, rounding_mode)…median_u256(vec, rounding_mode)
Errors
Functions
macro fun quick_sort<$Int>($vec: &mut vector<$Int>)
public
#Sorts an unsigned integer vector in ascending order in place. Generic over any unsigned integer type (u8, u16, u32, u64, u128, u256).
NOTE: Unstable sort. Average time complexity is O(n log n); theoretical worst case is O(n^2), mitigated by median-of-three pivot selection and three-way partitioning.
macro fun quick_sort_by<$T>($vec: &mut vector<$T>, $le: |&$T, &$T| -> bool)
public
#Sorts a vector in place using a caller-supplied comparison function. The comparator must implement non-strict ordering (<= for ascending, >= for descending). Using a strict comparator (< or >) defeats three-way partitioning and degrades performance to O(n^2) when duplicates are present.
NOTE: Unstable sort. The same complexity caveats as quick_sort apply.
macro fun median<$Int>($vec: &vector<$Int>, $rounding_mode: RoundingMode) -> $Int
public
#Computes the median of an unsigned integer vector ($Int in {u8, u16, u32, u64, u128, u256}) via quickselect, without mutating the input. For odd-length vectors the median is the central order statistic and $rounding_mode has no effect; for even-length vectors it is the average of the two central values, rounded according to $rounding_mode.
Inlines the full selection algorithm at every call site. For a precompiled alternative, use the median_u8 … median_u256 wrappers.
NOTE: Average time complexity is O(n) with O(n) extra storage for the working copy; theoretical worst case is O(n^2). Aborts with EMedianOfEmptyVector when $vec is empty.
median_<width>(vec: &vector<Int>, rounding_mode: RoundingMode) -> Int
public
#Precompiled wrappers around median!, one per unsigned width (median_u8, median_u16, median_u32, median_u64, median_u128, median_u256). Same algorithm, results, and abort behavior, but the selection bytecode is compiled once in the library instead of being inlined at the call site. Prefer these by default; reach for the macro when a call site is gas-critical.
Errors
EMedianOfEmptyVector (code 0)
error
#Raised when median! (or any median_* wrapper) is called on an empty vector, whose median is undefined.