Fixed-Point Math API Reference
This page documents the public API of openzeppelin_fp_math for OpenZeppelin Contracts for Sui v1.x.
The package provides two decimal fixed-point types with 9 decimals (matching Sui coin precision):
UD30x9: unsigned, backed byu128.SD29x9: signed (two's complement), backed byu128.
Each type has a base module that holds the arithmetic, comparison, and bitwise functions, and a conversion module that scales whole integers in and out of fixed-point form.
use openzeppelin_fp_math::ud30x9;Defines the UD30x9 unsigned decimal fixed-point type. Values represent unsigned real numbers as a u128 scaled by 10^9. The 9-decimal scale matches Sui coin precision and keeps offchain reasoning straightforward (1.0 is 1_000_000_000).
This module owns the type, raw casting helpers (wrap / unwrap), and constant constructors. Arithmetic, comparison, and bitwise operations live in ud30x9_base. Whole-integer conversions live in ud30x9_convert.
Types
Functions
Types
struct UD30x9(u128) has copy, drop, store
struct
#Unsigned decimal fixed-point type. The single u128 field stores the raw bits of the value scaled by 10^9.
Functions
zero() -> UD30x9
public
#Returns the UD30x9 representation of 0.
one() -> UD30x9
public
#Returns the UD30x9 representation of 1.0 (raw bits 10^9).
max() -> UD30x9
public
#Returns the largest representable UD30x9 value (raw bits u128::MAX).
wrap(x: u128) -> UD30x9
public
#Wraps raw u128 bits into a UD30x9 value without scaling. The input is interpreted as fixed-point bits already scaled by 10^9.
INFO: Use ud30x9_convert::from_u64 / from_u128 when the input is a whole integer that you mean as x.0.
unwrap(x: UD30x9) -> u128
public
#Returns the raw u128 bits of a UD30x9 value.
use openzeppelin_fp_math::ud30x9_base;Arithmetic, comparison, and bitwise functions for UD30x9. All entries are exported as method-style calls on UD30x9 via public use fun declarations in ud30x9, so x.add(y) and ud30x9_base::add(x, y) are equivalent.
Functions
- Arithmetic:
add,sub,mul,mul_trunc,mul_away,div,div_trunc,div_away,mod,pow,sqrt,ln,log2,log10,abs,ceil,floor,unchecked_add,unchecked_sub - Comparison:
eq,neq,gt,gte,lt,lte,is_zero - Bitwise:
and,and2,or,xor,not,lshift,unchecked_lshift,rshift,unchecked_rshift - Cross-type casts:
into_SD29x9,try_into_SD29x9
Errors
EOverflowEUnderflowEDivideByZeroECannotBeConvertedToSD29x9EInvalidShiftSizeELogUndefinedELogResultUnrepresentable
Functions
add(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the sum x + y.
Aborts with EOverflow if the sum exceeds the representable UD30x9 range.
sub(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the difference x - y.
Aborts with EUnderflow if y > x (the result would be negative, which is unrepresentable in UD30x9).
mul_trunc(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the product x * y, rounded toward zero (truncating the fractional part).
Aborts with EOverflow if the result exceeds the representable UD30x9 range.
mul_away(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the product x * y, rounded away from zero when inexact.
Aborts with EOverflow if the rounded result exceeds the representable UD30x9 range.
div_trunc(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the quotient x / y, rounded toward zero (truncating the fractional part).
Aborts with EDivideByZero if y is zero.
Aborts with EOverflow if the result exceeds the representable UD30x9 range.
div_away(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the quotient x / y, rounded away from zero when inexact. For example 1.0 / 3.0 returns 0.333333334.
Aborts with EDivideByZero if y is zero.
Aborts with EOverflow if the rounded result exceeds the representable UD30x9 range.
mod(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the remainder of x divided by y.
Aborts with EDivideByZero if y is zero.
pow(x: UD30x9, exp: u8) -> UD30x9
public
#Returns an approximation of x^exp computed using binary exponentiation with fixed-point multiplication. Each intermediate multiply or square applies fixed-point truncation.
Aborts with EOverflow if any intermediate or the final result exceeds the representable UD30x9 range.
NOTE: Because truncation is applied at intermediate steps, pow is approximate for most fractional values. Rounding error compounds as exp grows; results are biased toward zero; for 0 < x < 1 intermediate values can reach zero before the final mathematically scaled result would. Fixed-point multiplication is not associative under truncation, so the grouping used by binary exponentiation can affect the value.
sqrt(x: UD30x9) -> UD30x9
public
#Returns the largest UD30x9 value r such that r * r <= x. The result is rounded down to the nearest representable UD30x9 value.
ln(x: UD30x9) -> UD30x9
public
#Returns the natural logarithm of x, derived from log2 via ln(x) = log2(x) * ln(2). The result is rounded down and may sit up to 2 ulps below the true value.
Aborts with ELogUndefined if x is zero.
Aborts with ELogResultUnrepresentable if x is in (0, 1) (the result would be negative and cannot be represented in UD30x9 — use SD29x9::ln instead).
log2(x: UD30x9) -> UD30x9
public
#Returns the base-2 logarithm of x. The result is rounded down and sits at most 2 ulps below the true log2(x). For inputs in [1, 2) the result is exact.
Aborts with ELogUndefined if x is zero.
Aborts with ELogResultUnrepresentable if x is in (0, 1) (the result would be negative and cannot be represented in UD30x9 — use SD29x9::log2 instead).
log10(x: UD30x9) -> UD30x9
public
#Returns the base-10 logarithm of x. Exact when x is an integer power of ten (10^k, k >= 0). Otherwise derived from log2 via log10(x) = log2(x) * log10(2) and rounded down; the result may sit up to 2 ulps below the true value.
Aborts with ELogUndefined if x is zero.
Aborts with ELogResultUnrepresentable if x is in (0, 1) (the result would be negative and cannot be represented in UD30x9 — use SD29x9::log10 instead).
abs(x: UD30x9) -> UD30x9
public
#Returns x unchanged. UD30x9 is unsigned, so the absolute value is identity. Provided for symmetry with SD29x9::abs.
ceil(x: UD30x9) -> UD30x9
public
#Rounds toward positive infinity to the next integer multiple of 10^9. Returns x if it is already a whole multiple.
Aborts with EOverflow if the rounded result exceeds the representable UD30x9 range.
floor(x: UD30x9) -> UD30x9
public
#Rounds toward zero to the nearest integer multiple of 10^9.
unchecked_add(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the wrapping sum x + y modulo 2^128. Does not abort on overflow.
unchecked_sub(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the wrapping difference x - y modulo 2^128. Does not abort on underflow.
eq(x: UD30x9, y: UD30x9) -> bool
public
#Returns true if x == y.
neq(x: UD30x9, y: UD30x9) -> bool
public
#Returns true if x != y.
gt(x: UD30x9, y: UD30x9) -> bool
public
#Returns true if x > y.
gte(x: UD30x9, y: UD30x9) -> bool
public
#Returns true if x >= y.
lt(x: UD30x9, y: UD30x9) -> bool
public
#Returns true if x < y.
lte(x: UD30x9, y: UD30x9) -> bool
public
#Returns true if x <= y.
is_zero(x: UD30x9) -> bool
public
#Returns true if x is exactly zero.
and(x: UD30x9, bits: u128) -> UD30x9
public
#Returns the bitwise AND of x's raw bits and the u128 mask bits.
and2(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the bitwise AND of two UD30x9 raw bit patterns.
or(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the bitwise OR of two UD30x9 raw bit patterns.
xor(x: UD30x9, y: UD30x9) -> UD30x9
public
#Returns the bitwise XOR of two UD30x9 raw bit patterns.
not(x: UD30x9) -> UD30x9
public
#Returns the bitwise NOT of x's raw bits.
lshift(x: UD30x9, bits: u8) -> UD30x9
public
#Logical left shift on the underlying 128-bit representation by bits positions.
Aborts with EInvalidShiftSize if bits >= 128.
Aborts with EOverflow if the shift would consume non-zero high bits.
rshift(x: UD30x9, bits: u8) -> UD30x9
public
#Logical right shift on the underlying 128-bit representation by bits positions.
Aborts with EInvalidShiftSize if bits >= 128.
unchecked_rshift(x: UD30x9, bits: u8) -> UD30x9
public
#Logical right shift that returns zero when bits >= 128. Vacated high bits are filled with zeros.
into_SD29x9(x: UD30x9) -> SD29x9
public
#Casts a UD30x9 value to SD29x9 while preserving the scaled numeric meaning.
Aborts with ECannotBeConvertedToSD29x9 if x exceeds the maximum positive SD29x9 magnitude (2^127 - 1).
try_into_SD29x9(x: UD30x9) -> Option<SD29x9>
public
#Returns some(SD29x9) when the cast fits in the positive SD29x9 range, otherwise none.
Errors
EOverflow
error
#Raised when an arithmetic or shift result exceeds the representable UD30x9 range.
EUnderflow
error
#Raised when subtraction would produce a negative result, which is unrepresentable in UD30x9.
EDivideByZero
error
#Raised when a division or modulo operation receives a zero divisor.
ECannotBeConvertedToSD29x9
error
#Raised when into_SD29x9 is called on a value above the SD29x9 positive range.
use openzeppelin_fp_math::ud30x9_convert;Scale-aware conversions between whole unsigned integers and UD30x9. These functions apply or remove the 10^9 scale factor, so use them when your input or output represents a whole-integer quantity (e.g. 42 as 42.0).
For raw, non-scaling casts, use ud30x9::wrap and ud30x9::unwrap instead.
Functions
Errors
Functions
from_u64(x: u64) -> UD30x9
public
#Converts a whole u64 integer into UD30x9 by multiplying it by 10^9. Cannot overflow because u64::MAX * 10^9 fits in u128.
from_u128(x: u128) -> UD30x9
public
#Converts a whole u128 integer into UD30x9 by multiplying it by 10^9.
Aborts with EOverflow if x * 10^9 would overflow the UD30x9 raw representation.
try_from_u128(x: u128) -> Option<UD30x9>
public
#Returns some(UD30x9) when x * 10^9 fits in the raw representation, otherwise none.
to_u128_trunc(x: UD30x9) -> u128
public
#Returns the whole-number portion of x, computed as floor(x).
to_u64_trunc(x: UD30x9) -> u64
public
#Returns the truncated whole-number portion of x as u64.
Aborts with EIntegerOverflow if the truncated value exceeds u64::MAX.
try_to_u64_trunc(x: UD30x9) -> Option<u64>
public
#Returns some(u64) when the truncated whole-number portion fits in u64, otherwise none.
Errors
EOverflow
error
#Raised when a whole integer cannot be scaled into the UD30x9 raw representation.
EIntegerOverflow
error
#Raised when a truncated whole part does not fit in u64.
use openzeppelin_fp_math::sd29x9;Defines the SD29x9 signed decimal fixed-point type. Values represent signed real numbers as a two's complement u128 scaled by 10^9. Useful for balance deltas and any quantity that can dip below zero.
This module owns the type, raw casting helpers (wrap / unwrap), and constant constructors (zero, one, min, max). Arithmetic, comparison, and cross-type casts live in sd29x9_base. Whole-integer conversions live in sd29x9_convert.
Types
Functions
Errors
Types
struct SD29x9(u128) has copy, drop, store
struct
#Signed decimal fixed-point type. The single u128 field stores a two's complement representation scaled by 10^9.
Functions
zero() -> SD29x9
public
#Returns the SD29x9 representation of 0.
one() -> SD29x9
public
#Returns the SD29x9 representation of 1.0 (raw bits 10^9).
min() -> SD29x9
public
#Returns the smallest representable SD29x9 value, namely -2^127.
NOTE: +2^127 is not representable, so several arithmetic operations (such as abs and negate) abort when called on min.
max() -> SD29x9
public
#Returns the largest representable SD29x9 value, namely 2^127 - 1.
wrap(x: u128, is_negative: bool) -> SD29x9
public
#Wraps a u128 magnitude plus a sign flag into a raw SD29x9 value. The input must be a pure magnitude and must not already include a sign bit. When is_negative is true, the value is converted to its two's complement form.
Aborts with EOverflow if x exceeds the maximum positive magnitude (2^127 - 1).
NOTE: Cannot construct the minimum value. Use min for that.
unwrap(x: SD29x9) -> u128
public
#Returns the raw u128 two's complement bits of an SD29x9 value.
Errors
use openzeppelin_fp_math::sd29x9_base;Arithmetic, comparison, and cross-type casts for SD29x9. All entries are exported as method-style calls on SD29x9 via public use fun declarations in sd29x9, so x.add(y) and sd29x9_base::add(x, y) are equivalent.
Types
Functions
- Arithmetic:
add,sub,mul,mul_trunc,mul_away,div,div_trunc,div_away,mod,rem,pow,sqrt,ln,log2,log10,negate,abs,ceil,floor,unchecked_add,unchecked_sub - Comparison:
eq,neq,gt,gte,lt,lte,is_zero - Cross-type casts:
into_UD30x9,try_into_UD30x9
Errors
Types
struct Components { neg: bool, mag: u256 } has copy, drop
struct
#Signed decomposition of an SD29x9 value into a sign flag and a non-negative magnitude as u256. Returned by internal helpers; surfaced publicly so downstream tooling can pattern-match on it.
Functions
add(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the sum x + y.
Aborts with EOverflow if the resulting magnitude exceeds the representable SD29x9 range.
sub(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the difference x - y.
Aborts with EOverflow if the resulting magnitude exceeds the representable SD29x9 range.
mul_trunc(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the product x * y, rounded toward zero (truncating).
Aborts with EOverflow if the result exceeds the representable SD29x9 range.
mul_away(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the product x * y, rounded away from zero when inexact. For example 1.000000001 * 1.000000001 returns 1.000000003, and -1.000000001 * 1.000000001 returns -1.000000003.
Aborts with EOverflow if the rounded magnitude exceeds the representable SD29x9 range.
div_trunc(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the quotient x / y, rounded toward zero (truncating).
Aborts with EDivideByZero if y is zero.
Aborts with EOverflow if the result exceeds the representable SD29x9 range.
div_away(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the quotient x / y, rounded away from zero when inexact. For example 1.0 / 3.0 returns 0.333333334, and -1.0 / 3.0 returns -0.333333334.
Aborts with EDivideByZero if y is zero.
Aborts with EOverflow if the rounded magnitude exceeds the representable SD29x9 range.
rem(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the truncating remainder of x divided by y. The magnitude is abs(x) % abs(y) and the sign of the result follows the dividend x.
Aborts with EDivideByZero if y is zero.
NOTE: rem follows truncating remainder semantics. Use mod for Euclidean (always non-negative) remainder.
mod(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the Euclidean remainder of x divided by y. The result is always non-negative and satisfies 0 <= result < abs(y).
Aborts with EDivideByZero if y is zero.
pow(x: SD29x9, exp: u8) -> SD29x9
public
#Returns an approximation of x^exp computed using binary exponentiation with fixed-point multiplication. Each intermediate multiply or square applies fixed-point truncation.
Aborts with EOverflow if any intermediate or the final result exceeds the representable SD29x9 range.
NOTE: As with UD30x9::pow, results are biased toward zero, error compounds with exp, and binary-exponentiation grouping affects the value because fixed-point multiplication is not associative under truncation.
sqrt(x: SD29x9) -> SD29x9
public
#Returns the largest non-negative SD29x9 value r such that r * r <= x. The result is rounded down to the nearest representable SD29x9 value.
Aborts with ENegativeSqrt if x is negative.
log2(x: SD29x9) -> SD29x9
public
#Returns the base-2 logarithm of x, rounded toward zero (matching the convention used by mul_trunc, div_trunc, and pow in this module). For positive results (inputs >= 1) this coincides with rounding down and sits at most 2 ulps below the true value. For negative results (inputs in (0, 1)) the signed result usually sits closer to zero than the true value, but in narrow edge cases where the kernel's small upward magnitude bias crosses an integer boundary it may instead be 1 ulp further from zero.
Aborts with ELogUndefined if x is zero or negative.
log10(x: SD29x9) -> SD29x9
public
#Returns the base-10 logarithm of x. Exact when x is an integer power of ten, including sub-unit powers 10^-k (k in 1..=9). Otherwise derived from log2 via log10(x) = log2(x) * log10(2) and rounded toward zero; see log2 for full rounding semantics on signed results.
Aborts with ELogUndefined if x is zero or negative.
negate(x: SD29x9) -> SD29x9
public
#Returns -x.
Aborts with EOverflow if x is the minimum representable value (-2^127), because +2^127 is not representable.
abs(x: SD29x9) -> SD29x9
public
#Returns the absolute value of x.
Aborts with EOverflow if x is the minimum representable value (-2^127).
ceil(x: SD29x9) -> SD29x9
public
#Rounds toward positive infinity to the nearest integer multiple of 10^9.
Aborts with EOverflow if the rounded result exceeds the representable SD29x9 range.
floor(x: SD29x9) -> SD29x9
public
#Rounds toward negative infinity to the nearest integer multiple of 10^9.
Aborts with EOverflow if the rounded negative result magnitude exceeds the representable SD29x9 range.
unchecked_add(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the wrapping sum of the raw bit patterns modulo 2^128. Does not abort on overflow.
unchecked_sub(x: SD29x9, y: SD29x9) -> SD29x9
public
#Returns the wrapping difference of the raw bit patterns modulo 2^128. Does not abort on underflow.
eq(x: SD29x9, y: SD29x9) -> bool
public
#Returns true if x and y have identical underlying bits.
neq(x: SD29x9, y: SD29x9) -> bool
public
#Returns true if x != y.
gt(x: SD29x9, y: SD29x9) -> bool
public
#Returns true if x > y under signed comparison.
gte(x: SD29x9, y: SD29x9) -> bool
public
#Returns true if x >= y under signed comparison.
lt(x: SD29x9, y: SD29x9) -> bool
public
#Returns true if x < y under signed comparison.
lte(x: SD29x9, y: SD29x9) -> bool
public
#Returns true if x <= y under signed comparison.
is_zero(x: SD29x9) -> bool
public
#Returns true if x is exactly zero.
into_UD30x9(x: SD29x9) -> UD30x9
public
#Casts a non-negative SD29x9 value to UD30x9 while preserving the scaled numeric meaning.
Aborts with ECannotBeConvertedToUD30x9 if x is negative.
try_into_UD30x9(x: SD29x9) -> Option<UD30x9>
public
#Returns some(UD30x9) when x is non-negative, otherwise none.
Errors
EOverflow
error
#Raised when an arithmetic result exceeds the representable SD29x9 range.
EDivideByZero
error
#Raised when a division, modulo, or remainder operation receives a zero divisor.
ECannotBeConvertedToUD30x9
error
#Raised when into_UD30x9 is called on a negative value.
use openzeppelin_fp_math::sd29x9_convert;Scale-aware conversions between whole signed magnitudes and SD29x9. Inputs use an unsigned magnitude plus a sign flag because Move does not provide a native signed integer type for this package; outputs return either a single magnitude (when sign is asserted) or a (magnitude, is_negative) pair.
For raw, non-scaling casts, use sd29x9::wrap and sd29x9::unwrap instead.
Functions
from_u64(x, is_negative)from_u128(x, is_negative)try_from_u128(x, is_negative)to_parts_trunc(x)to_u128_trunc(x)try_to_u128_trunc(x)to_u64_trunc(x)try_to_u64_trunc(x)
Errors
Functions
from_u64(x: u64, is_negative: bool) -> SD29x9
public
#Converts a whole u64 magnitude into SD29x9 by multiplying it by 10^9 and applying the provided sign.
from_u128(x: u128, is_negative: bool) -> SD29x9
public
#Converts a whole u128 magnitude into SD29x9 by multiplying it by 10^9 and applying the provided sign.
Aborts with EOverflow if x * 10^9 would overflow the SD29x9 raw representation.
try_from_u128(x: u128, is_negative: bool) -> Option<SD29x9>
public
#Returns some(SD29x9) when the scaled magnitude fits, otherwise none.
to_parts_trunc(x: SD29x9) -> (u128, bool)
public
#Returns (magnitude, is_negative) where magnitude is the truncated whole-number portion of abs(x). is_negative is always false when the magnitude is zero.
to_u128_trunc(x: SD29x9) -> u128
public
#Returns the truncated whole-number portion of x as u128.
Aborts with ENegativeValue if x is negative.
try_to_u128_trunc(x: SD29x9) -> Option<u128>
public
#Returns some(u128) when x is non-negative, otherwise none.
to_u64_trunc(x: SD29x9) -> u64
public
#Returns the truncated whole-number portion of x as u64.
Aborts with ENegativeValue if x is negative.
Aborts with EIntegerOverflow if the truncated magnitude exceeds u64::MAX.
try_to_u64_trunc(x: SD29x9) -> Option<u64>
public
#Returns some(u64) when x is non-negative and the truncated whole-number portion fits in u64, otherwise none.
Errors
EOverflow
error
#Raised when a whole signed magnitude cannot be scaled into the SD29x9 raw representation.
ENegativeValue
error
#Raised when a negative SD29x9 value is converted to an unsigned integer type.
EIntegerOverflow
error
#Raised when a truncated whole part does not fit in u64.