Join our community of builders on

Telegram!Telegram
API Reference

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 by u128.
  • SD29x9: signed (two's complement), backed by u128.

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

Errors

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(x: UD30x9, y: UD30x9) -> UD30x9

public

#

Returns the product x * y, rounded toward zero. Equivalent to mul_trunc.

Aborts with EOverflow if the result exceeds the representable UD30x9 range.

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(x: UD30x9, y: UD30x9) -> UD30x9

public

#

Returns the quotient x / y, rounded toward zero. Equivalent to div_trunc.

Aborts with EDivideByZero if y is zero. Aborts with EOverflow if the 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.

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.

unchecked_lshift(x: UD30x9, bits: u8) -> UD30x9

public

#

Logical left shift that truncates high bits past the 128-bit boundary and returns zero when bits >= 128.

NOTE: Use lshift when you want shift-size and overflow checks to abort.

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.

EInvalidShiftSize

error

#

Raised when lshift or rshift is called with bits >= 128.

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

EOverflow

error

#

Raised when wrap is called with a magnitude that exceeds 2^127 - 1.

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

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(x: SD29x9, y: SD29x9) -> SD29x9

public

#

Returns the product x * y, rounded toward zero. Equivalent to mul_trunc.

Aborts with EOverflow if the result 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(x: SD29x9, y: SD29x9) -> SD29x9

public

#

Returns the quotient x / y, rounded toward zero. Equivalent to div_trunc.

Aborts with EDivideByZero if y is zero. Aborts with EOverflow if the result 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.

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

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.