#[repr(transparent)]pub struct I128<const SCALE: u32>(pub i128);Expand description
Scaled fixed-point decimal with 128-bit storage.
SCALE is the base-10 exponent. A logical value v is stored as
v * 10^SCALE in the underlying i128. For example, with SCALE = 12
the number 1.5 is stored as i128(1_500_000_000_000).
§Precision
N/A: type definition, no arithmetic performed.
§Determinism
All arithmetic is integer arithmetic on i128. The same inputs produce
the same bit-pattern on every platform.
§Equality and ordering
Hash, Eq, and Ord are derived from i128. Two I128<S> values
are equal if and only if their underlying i128 fields are bit-equal.
This works because the scale is fixed at compile time – each logical
value has exactly one representation.
§Const-generic scale
The const generic allows scale variants (I128<9>, I128<6>, etc.)
as trivial type aliases without duplicating any method implementations.
Mixed-scale arithmetic is deliberately not provided; callers convert
explicitly.
Tuple Fields§
§0: i128Implementations§
Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub const fn abs(self) -> Self
pub const fn abs(self) -> Self
Return the absolute value of self.
§Panics
Panics in debug builds when self == I128::MIN because i128::MIN
has no positive counterpart in two’s-complement. Wraps to i128::MIN
in release builds.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let x = I128s12::from_bits(-1_500_000_000_000);
assert_eq!(x.abs().to_bits(), 1_500_000_000_000);Sourcepub fn signum(self) -> Self
pub fn signum(self) -> Self
Return the sign of self as a scaled I128.
Returns -ONE for negative values, ZERO for zero, and +ONE
for positive values, mirroring f64::signum / i128::signum lifted
into the I128 type. Unlike i128::signum which returns a bare
-1, 0, or 1, this method encodes the result as N * 10^S.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_bits(500_000_000_000).signum(), I128s12::ONE);
assert_eq!(I128s12::ZERO.signum(), I128s12::ZERO);
assert_eq!(I128s12::from_bits(-500_000_000_000).signum(), -I128s12::ONE);Sourcepub fn floor(self) -> Self
pub fn floor(self) -> Self
Return the largest integer multiple of ONE that is less than or
equal to self (round toward negative infinity).
For negative inputs this differs from truncation:
I128(-0.5).floor() returns I128(-1.0), not I128(0.0).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let x = I128s12::from_bits(2_500_000_000_000); // 2.5
assert_eq!(x.floor().to_bits(), 2_000_000_000_000);
let y = I128s12::from_bits(-2_500_000_000_000); // -2.5
assert_eq!(y.floor().to_bits(), -3_000_000_000_000);Sourcepub fn ceil(self) -> Self
pub fn ceil(self) -> Self
Return the smallest integer multiple of ONE that is greater than
or equal to self (round toward positive infinity).
For negative inputs: I128(-0.5).ceil() returns I128(0.0).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let x = I128s12::from_bits(2_500_000_000_000); // 2.5
assert_eq!(x.ceil().to_bits(), 3_000_000_000_000);
let y = I128s12::from_bits(-2_500_000_000_000); // -2.5
assert_eq!(y.ceil().to_bits(), -2_000_000_000_000);Sourcepub fn round(self) -> Self
pub fn round(self) -> Self
Round to the nearest integer using half-away-from-zero.
Ties (values whose fractional part is exactly 0.5) round away from
zero: 2.5 rounds to 3.0 and -2.5 rounds to -3.0. This
matches f64::round. Half-even (“banker’s”) rounding is not
provided; use floor and fract to compose it if needed.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_bits(2_500_000_000_000).round().to_bits(), 3_000_000_000_000);
assert_eq!(I128s12::from_bits(2_400_000_000_000).round().to_bits(), 2_000_000_000_000);
assert_eq!(I128s12::from_bits(-2_500_000_000_000).round().to_bits(), -3_000_000_000_000);Sourcepub fn trunc(self) -> Self
pub fn trunc(self) -> Self
Drop the fractional part, rounding toward zero.
For negative inputs this differs from floor:
I128(-2.5).trunc() returns I128(-2.0), whereas
I128(-2.5).floor() returns I128(-3.0).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_bits(2_500_000_000_000).trunc().to_bits(), 2_000_000_000_000);
assert_eq!(I128s12::from_bits(-2_500_000_000_000).trunc().to_bits(), -2_000_000_000_000);Sourcepub fn fract(self) -> Self
pub fn fract(self) -> Self
Return only the fractional part: self - self.trunc().
The result has the same sign as self because trunc rounds toward
zero. I128(2.5).fract() is I128(0.5); I128(-2.5).fract() is
I128(-0.5).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_bits(2_500_000_000_000).fract().to_bits(), 500_000_000_000);
assert_eq!(I128s12::from_bits(-2_500_000_000_000).fract().to_bits(), -500_000_000_000);
assert_eq!(I128s12::from_bits(2_000_000_000_000).fract().to_bits(), 0);Sourcepub fn clamp(self, lo: Self, hi: Self) -> Self
pub fn clamp(self, lo: Self, hi: Self) -> Self
Restrict self to the closed interval [lo, hi].
Returns lo if self < lo, hi if self > hi, and self
otherwise.
§Panics
Panics if lo > hi, matching Ord::clamp.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let lo = I128s12::from_bits(1_000_000_000_000); // 1.0
let hi = I128s12::from_bits(3_000_000_000_000); // 3.0
let x = I128s12::from_bits(5_000_000_000_000); // 5.0
assert_eq!(x.clamp(lo, hi), hi);Sourcepub fn recip(self) -> Self
pub fn recip(self) -> Self
Return the multiplicative inverse: ONE / self.
§Panics
Panics when self == ZERO (division by zero).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let two = I128s12::from_bits(2_000_000_000_000);
let half = I128s12::from_bits(500_000_000_000);
assert_eq!(two.recip(), half);Sourcepub fn copysign(self, sign: Self) -> Self
pub fn copysign(self, sign: Self) -> Self
Return a value with the magnitude of self and the sign of sign.
When sign == ZERO the result is positive because i128 has no
negative-zero representation.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let pos = I128s12::from_bits(1_500_000_000_000);
let neg = I128s12::from_bits(-2_000_000_000_000);
assert_eq!(pos.copysign(neg).to_bits(), -1_500_000_000_000);Sourcepub fn div_euclid(self, rhs: Self) -> Self
pub fn div_euclid(self, rhs: Self) -> Self
Euclidean division: returns the quotient as a I128 integer multiple
of ONE, chosen so that the remainder is non-negative.
Delegates to i128::div_euclid on the raw storage values; the
quotient is rescaled by multiplier() to produce a value in
N * 10^S form.
§Panics
Panics on rhs == ZERO and on overflow in debug builds (e.g.
I128::MIN.div_euclid(-ONE) overflows the quotient, mirroring
i128::div_euclid).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(-5_000_000_000_000); // -5.0
let b = I128s12::from_bits( 2_000_000_000_000); // 2.0
// Euclidean: quotient = -3, remainder = 1 (always non-negative)
assert_eq!(a.div_euclid(b).to_bits(), -3_000_000_000_000);Sourcepub fn rem_euclid(self, rhs: Self) -> Self
pub fn rem_euclid(self, rhs: Self) -> Self
Euclidean remainder: self - rhs * self.div_euclid(rhs).
The result is always non-negative when rhs != ZERO. Because both
operands share the same scale, self.0.rem_euclid(rhs.0) already
lives in value * 10^S form without rescaling.
§Panics
Panics on rhs == ZERO.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(-5_000_000_000_000); // -5.0
let b = I128s12::from_bits( 2_000_000_000_000); // 2.0
assert_eq!(a.rem_euclid(b).to_bits(), 1_000_000_000_000); // 1.0, non-negativeSourcepub fn div_floor(self, rhs: Self) -> Self
pub fn div_floor(self, rhs: Self) -> Self
Floor-rounded division: returns floor(self / rhs) as a I128
integer multiple of ONE.
Differs from div_euclid for negative divisors: div_floor is
keyed to the real-number quotient, while div_euclid is keyed to
keeping the remainder non-negative regardless of divisor sign.
Implemented inline because i128::div_floor for signed types is
still behind an unstable feature as of Rust 1.95.
§Panics
Panics on rhs == ZERO.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(-5_000_000_000_000); // -5.0
let b = I128s12::from_bits( 2_000_000_000_000); // 2.0
// floor(-2.5) = -3
assert_eq!(a.div_floor(b).to_bits(), -3_000_000_000_000);Sourcepub fn div_ceil(self, rhs: Self) -> Self
pub fn div_ceil(self, rhs: Self) -> Self
Ceil-rounded division: returns ceil(self / rhs) as a I128
integer multiple of ONE.
Implemented inline because i128::div_ceil for signed types is
still behind an unstable feature as of Rust 1.95.
§Panics
Panics on rhs == ZERO.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(5_000_000_000_000); // 5.0
let b = I128s12::from_bits(2_000_000_000_000); // 2.0
// ceil(2.5) = 3
assert_eq!(a.div_ceil(b).to_bits(), 3_000_000_000_000);Sourcepub fn abs_diff(self, rhs: Self) -> Self
pub fn abs_diff(self, rhs: Self) -> Self
Return the absolute difference |self - rhs| as a I128.
Computed as max(self, rhs) - min(self, rhs) so the subtraction
is always non-negative. Returns a signed I128 rather than a u128
because I128 uses signed storage. Standard panic-debug /
wrap-release applies if the difference exceeds i128::MAX (only
possible at the MAX - MIN boundary).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits( 5_000_000_000_000); // 5.0
let b = I128s12::from_bits(-2_000_000_000_000); // -2.0
assert_eq!(a.abs_diff(b).to_bits(), 7_000_000_000_000); // 7.0Sourcepub fn midpoint(self, rhs: Self) -> Self
pub fn midpoint(self, rhs: Self) -> Self
Return the midpoint of self and rhs without intermediate
overflow.
Delegates to i128::midpoint (stable since Rust 1.85). Rounds
toward negative infinity when the exact midpoint is not
representable, matching i128::midpoint semantics.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(1_000_000_000_000); // 1.0
let b = I128s12::from_bits(3_000_000_000_000); // 3.0
assert_eq!(a.midpoint(b).to_bits(), 2_000_000_000_000); // 2.0Sourcepub const fn is_infinite(self) -> bool
pub const fn is_infinite(self) -> bool
Sourcepub const fn is_normal(self) -> bool
pub const fn is_normal(self) -> bool
Returns true for any non-zero value.
I128 has no subnormal representation, so zero is the only value
that is not normal.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert!(!I128s12::ZERO.is_normal());
assert!(I128s12::ONE.is_normal());Sourcepub const fn is_positive(self) -> bool
pub const fn is_positive(self) -> bool
Sourcepub const fn is_negative(self) -> bool
pub const fn is_negative(self) -> bool
Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub const fn unsigned_shr(self, n: u32) -> Self
pub const fn unsigned_shr(self, n: u32) -> Self
Logical (zero-fill) right shift of the underlying i128 storage
by n bits.
Unlike the Shr operator, which is arithmetic (sign-extending),
this method reinterprets storage as u128 for the shift, so the
vacated high bits are always filled with zeros regardless of sign.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Panics
Panics in debug builds when n >= 128; wraps modulo 128 in
release builds.
§Examples
use decimal_scaled::I128s12;
// -1 raw is all-ones. Arithmetic shr keeps it all-ones;
// unsigned_shr clears the top bit, giving i128::MAX.
let neg_one = I128s12::from_bits(-1);
assert_eq!(neg_one >> 1u32, neg_one); // sign-extending
assert_eq!(neg_one.unsigned_shr(1), I128s12::from_bits(i128::MAX)); // zero-fillSourcepub const fn rotate_left(self, n: u32) -> Self
pub const fn rotate_left(self, n: u32) -> Self
Rotate the underlying i128 storage left by n bits. Bits
shifted off the high end wrap into the low end.
Operates on raw bits, not the logical decimal value.
Delegates to i128::rotate_left.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
// 0b111 rotated left by 1 = 0b1110.
assert_eq!(I128s12::from_bits(0b111).rotate_left(1), I128s12::from_bits(0b1110));Sourcepub const fn rotate_right(self, n: u32) -> Self
pub const fn rotate_right(self, n: u32) -> Self
Rotate the underlying i128 storage right by n bits. Bits
shifted off the low end wrap into the high end.
Operates on raw bits, not the logical decimal value.
Delegates to i128::rotate_right.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
// 1 rotated right by 1 wraps the low bit to the top: i128::MIN.
assert_eq!(I128s12::from_bits(1).rotate_right(1), I128s12::from_bits(i128::MIN));Sourcepub const fn leading_zeros(self) -> u32
pub const fn leading_zeros(self) -> u32
Number of leading zero bits in the underlying i128 storage.
Returns 128 for storage value 0, 127 for 1, and 0 for
from_bits(-1) (all-ones). Delegates to i128::leading_zeros.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_bits(1).leading_zeros(), 127);
assert_eq!(I128s12::ZERO.leading_zeros(), 128);
assert_eq!(I128s12::from_bits(-1).leading_zeros(), 0);Sourcepub const fn trailing_zeros(self) -> u32
pub const fn trailing_zeros(self) -> u32
Number of trailing zero bits in the underlying i128 storage.
Returns 128 for storage value 0 and 3 for from_bits(8).
Delegates to i128::trailing_zeros.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_bits(8).trailing_zeros(), 3);
assert_eq!(I128s12::ZERO.trailing_zeros(), 128);Sourcepub const fn count_ones(self) -> u32
pub const fn count_ones(self) -> u32
Population count: number of 1 bits set in the underlying i128
storage.
Note the storage-not-value semantic: I128s12::ONE.count_ones()
returns the popcount of 10^12 (= 21), not 1. Use
I128::from_bits when you need a predictable bit pattern.
Delegates to i128::count_ones.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_bits(0b101).count_ones(), 2);Sourcepub const fn count_zeros(self) -> u32
pub const fn count_zeros(self) -> u32
Number of 0 bits in the underlying i128 storage. Always equal
to 128 - self.count_ones().
Delegates to i128::count_zeros.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
// 0b101 has 2 ones and 126 zeros in 128-bit storage.
assert_eq!(I128s12::from_bits(0b101).count_zeros(), 126);Sourcepub const fn is_power_of_two(self) -> bool
pub const fn is_power_of_two(self) -> bool
Returns true if the underlying i128 storage is a power of two
(exactly one bit set and the value is positive).
Implemented by reinterpreting the storage as u128 and delegating
to u128::is_power_of_two. Negative i128 values always return
false because the sign bit being set means more than one bit is
set in the u128 view.
Note the storage-not-value semantic: I128s12::ONE.is_power_of_two()
returns false because storage is 10^12 = 2^12 * 5^12, not a
single-bit value.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert!(I128s12::from_bits(8).is_power_of_two());
assert!(!I128s12::from_bits(7).is_power_of_two());
assert!(!I128s12::from_bits(-1).is_power_of_two());Sourcepub const fn next_power_of_two(self) -> Self
pub const fn next_power_of_two(self) -> Self
Smallest power of two greater than or equal to the underlying
i128 storage, treating the storage as u128.
Delegates to u128::next_power_of_two over the unsigned
reinterpretation, then casts the result back to i128. If the
next power of two exceeds i128::MAX the raw bit pattern wraps
into the negative i128 range.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Panics
Panics in debug builds when the next power of two overflows
u128::MAX, matching u128::next_power_of_two semantics.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_bits(7).next_power_of_two(), I128s12::from_bits(8));
assert_eq!(I128s12::from_bits(8).next_power_of_two(), I128s12::from_bits(8));Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub const EPSILON: Self
pub const EPSILON: Self
Smallest representable positive value: 1 LSB = 10^-SCALE.
Provided as an analogue to f64::EPSILON for generic numeric code.
Note that this differs from the f64 definition (“difference between
1.0 and the next-larger f64”): for I128 the LSB is uniform across
the entire representable range.
§Precision
N/A: constant value, no arithmetic performed.
Sourcepub const MIN_POSITIVE: Self
pub const MIN_POSITIVE: Self
Smallest positive value (equal to Self::EPSILON).
Provided as an analogue to f64::MIN_POSITIVE for generic numeric
code. Unlike f64, I128 has no subnormals, so MIN_POSITIVE
and EPSILON are the same value.
§Precision
N/A: constant value, no arithmetic performed.
Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub fn from_int(value: i64) -> Self
pub fn from_int(value: i64) -> Self
Constructs a I128 from an i64 integer value.
Named constructor that wraps From<i64>. Prefer this over
I128::from(value) when the intent of converting from an integer
should be explicit at the call site.
At SCALE = 12 every i64 value fits with roughly six orders of
magnitude of headroom before i128::MAX.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_int(1), I128s12::ONE);
assert_eq!(I128s12::from_int(-42).to_bits(), -42_000_000_000_000_i128);Sourcepub fn from_i32(value: i32) -> Self
pub fn from_i32(value: i32) -> Self
Constructs a I128 from an i32 integer value.
Named constructor that wraps From<i32>. Lossless at any
practical SCALE (safe up to SCALE < 28).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_i32(1), I128s12::ONE);
assert_eq!(I128s12::from_i32(0), I128s12::ZERO);Sourcepub fn from_f64_lossy(value: f64) -> Self
pub fn from_f64_lossy(value: f64) -> Self
Constructs a I128 from an f64, saturating on non-finite or
out-of-range inputs.
Multiplies value by 10^SCALE and truncates to i128. Non-finite
and out-of-range inputs are handled as follows:
NaNreturnsI128::ZERO(deterministic, no panic).+infor any finite value above the representable range returnsI128::MAX.-infor any finite value below the representable range returnsI128::MIN.
Use TryFrom<f64> when you want an error instead of saturation.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_f64_lossy(1.0), I128s12::ONE);
assert_eq!(I128s12::from_f64_lossy(f64::NAN), I128s12::ZERO);
assert_eq!(I128s12::from_f64_lossy(f64::INFINITY), I128s12::MAX);
assert_eq!(I128s12::from_f64_lossy(f64::NEG_INFINITY), I128s12::MIN);Sourcepub fn to_int_lossy(self) -> i64
pub fn to_int_lossy(self) -> i64
Converts to i64 by truncating the fractional part toward zero.
The integer part is self.0 / 10^SCALE. If that value exceeds
i64::MAX or falls below i64::MIN, the result saturates to
i64::MAX or i64::MIN respectively. At SCALE = 12 the saturation
threshold is approximately 9.2e18 (the i64 limit), which is well
below the I128 maximum of ~1.7e26.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// Truncates toward zero.
assert_eq!(I128s12::from_bits(2_500_000_000_000).to_int_lossy(), 2);
assert_eq!(I128s12::from_bits(-2_500_000_000_000).to_int_lossy(), -2);
// Saturates when the integer part exceeds i64 range.
assert_eq!(I128s12::MAX.to_int_lossy(), i64::MAX);
assert_eq!(I128s12::MIN.to_int_lossy(), i64::MIN);Sourcepub fn to_f64_lossy(self) -> f64
pub fn to_f64_lossy(self) -> f64
Converts to f64 by dividing the raw storage by 10^SCALE.
f64 has a 53-bit mantissa, so large or precision-dense I128 values
will round. The division is performed as (self.0 as f64) / multiplier
to keep as much precision as f64 allows.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::ZERO.to_f64_lossy(), 0.0);
assert_eq!(I128s12::ONE.to_f64_lossy(), 1.0);Sourcepub fn to_f32_lossy(self) -> f32
pub fn to_f32_lossy(self) -> f32
Converts to f32 via f64, then narrows to f32.
f32 has only a 24-bit mantissa, making this lossier than
Self::to_f64_lossy. The f64 intermediate step retains the
best precision available before the final narrowing cast.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::ZERO.to_f32_lossy(), 0.0_f32);
assert_eq!(I128s12::ONE.to_f32_lossy(), 1.0_f32);Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub const ONE: Self
pub const ONE: Self
The multiplicative identity. Stored as i128(10^SCALE).
At SCALE = 12 the raw value is 1_000_000_000_000.
§Precision
N/A: constant value, no arithmetic performed.
Sourcepub const MAX: Self
pub const MAX: Self
The largest representable value: I128(i128::MAX).
In logical terms this is i128::MAX / 10^SCALE. At SCALE = 12
that is approximately 1.7e14 model units. Arithmetic that overflows
this bound panics in debug builds and wraps in release builds.
§Precision
N/A: constant value, no arithmetic performed.
Sourcepub const fn from_bits(raw: i128) -> Self
pub const fn from_bits(raw: i128) -> Self
Constructs a I128<SCALE> from a raw i128 bit pattern.
The integer is interpreted directly as the internal storage:
raw represents the logical value raw * 10^(-SCALE). This is the
inverse of Self::to_bits.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
// Raw 1_500_000_000_000 represents the logical value 1.5.
let v = I128s12::from_bits(1_500_000_000_000);
assert_eq!(v.to_bits(), 1_500_000_000_000);Sourcepub const fn to_bits(self) -> i128
pub const fn to_bits(self) -> i128
Returns the raw i128 storage value.
The returned integer encodes the logical value self * 10^SCALE.
This is the inverse of Self::from_bits.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::ONE.to_bits(), 1_000_000_000_000_i128);Sourcepub const fn multiplier() -> i128
pub const fn multiplier() -> i128
Returns 10^SCALE, the factor that converts a logical integer value
to its storage representation.
This equals the bit pattern of Self::ONE.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Overflow
10^SCALE overflows i128 at SCALE >= 39. For practical scales
(SCALE <= 38) this is within range. Calling with an overflowing
scale panics at compile time when the const item is evaluated.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::multiplier(), 1_000_000_000_000_i128);Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub fn from_num<T: ToPrimitive>(value: T) -> Self
pub fn from_num<T: ToPrimitive>(value: T) -> Self
Constructs a I128<SCALE> from any T: ToPrimitive.
This is a compatibility alias for the idiomatic From<T> /
num_traits::FromPrimitive surface. Routes through
num_traits::NumCast::from, which dispatches to the
num_traits::FromPrimitive impl on I128.
§Precision
Lossy: involves f32 or f64 at some point when T is a float type;
result may lose precision. For integer T, the conversion is Strict:
all arithmetic is integer-only; result is bit-exact.
§Saturation policy
- Float
NaNmaps toI128::ZERO. +Infinitymaps toI128::MAX.-Infinitymaps toI128::MIN.- Finite out-of-range positive maps to
I128::MAX. - Finite out-of-range negative maps to
I128::MIN. - Never panics.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_num(42_i32), I128s12::from(42_i32));
assert_eq!(I128s12::from_num(f64::INFINITY), I128s12::MAX);
assert_eq!(I128s12::from_num(f64::NAN), I128s12::ZERO);Sourcepub fn to_num<T: NumCast + Bounded>(self) -> T
pub fn to_num<T: NumCast + Bounded>(self) -> T
Converts self to any T: NumCast + Bounded.
This is a compatibility alias for the idiomatic
num_traits::ToPrimitive / to_X_lossy surface. Routes through
num_traits::NumCast::from, which dispatches to the
num_traits::ToPrimitive impl on I128.
§Precision
Lossy: involves f32 or f64 at some point when T is a float type;
result may lose precision. For integer T, the conversion is Strict:
all arithmetic is integer-only; result is bit-exact.
§Saturation policy
- In-range conversions return the cast value unchanged.
- Positive out-of-range maps to
Bounded::max_valueofT. - Negative out-of-range maps to
Bounded::min_valueofT. - Never panics.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from(42_i32).to_num::<i32>(), 42_i32);
assert_eq!(I128s12::MAX.to_num::<i32>(), i32::MAX);
assert_eq!(I128s12::MIN.to_num::<i32>(), i32::MIN);Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub fn ln(self) -> Self
pub fn ln(self) -> Self
Returns the natural logarithm (base e) of self.
§Precision
Lossy: converts to f64, calls f64::ln, converts back. f64::ln
returns -Infinity for 0.0 (saturates to I128::MIN) and NaN
for negative inputs (maps to I128::ZERO).
§Examples
use decimal_scaled::I128s12;
// ln(1) == 0 (f64::ln(1.0) == 0.0 exactly).
assert_eq!(I128s12::ONE.ln(), I128s12::ZERO);Sourcepub fn log(self, base: Self) -> Self
pub fn log(self, base: Self) -> Self
Returns the logarithm of self in the given base.
Implemented via a single f64::log(self_f64, base_f64) call, which
avoids the extra quantisation that would come from computing
ln(self) / ln(base) with two separate f64 round-trips.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// log_2(8) is approximately 3 within f64 precision.
let eight = I128s12::from_int(8);
let two = I128s12::from_int(2);
let result = eight.log(two);Sourcepub fn log2(self) -> Self
pub fn log2(self) -> Self
Returns the base-2 logarithm of self.
§Precision
Lossy: involves f64 at some point; result may lose precision.
On IEEE-754 platforms, f64::log2 is exact for integer powers
of two (e.g. log2(8.0) == 3.0). Out-of-domain inputs follow
the same saturation policy as Self::ln.
§Examples
use decimal_scaled::I128s12;
// log2(1) == 0 (f64::log2(1.0) == 0.0 exactly).
assert_eq!(I128s12::ONE.log2(), I128s12::ZERO);Sourcepub fn log10(self) -> Self
pub fn log10(self) -> Self
Returns the base-10 logarithm of self.
§Precision
Lossy: involves f64 at some point; result may lose precision.
Out-of-domain inputs follow the same saturation policy as Self::ln.
§Examples
use decimal_scaled::I128s12;
// log10(1) == 0 (f64::log10(1.0) == 0.0 exactly).
assert_eq!(I128s12::ONE.log10(), I128s12::ZERO);Sourcepub fn exp(self) -> Self
pub fn exp(self) -> Self
Returns e^self (natural exponential).
§Precision
Lossy: involves f64 at some point; result may lose precision.
Large positive inputs overflow f64 to +Infinity, which saturates
to I128::MAX. Large negative inputs underflow to 0.0 in f64,
which maps to I128::ZERO.
§Examples
use decimal_scaled::I128s12;
// exp(0) == 1 (f64::exp(0.0) == 1.0 exactly).
assert_eq!(I128s12::ZERO.exp(), I128s12::ONE);Sourcepub fn exp2(self) -> Self
pub fn exp2(self) -> Self
Returns 2^self (base-2 exponential).
§Precision
Lossy: involves f64 at some point; result may lose precision.
Saturation behaviour is analogous to Self::exp but at different
magnitudes (inputs beyond approximately 1024 overflow to +Infinity).
§Examples
use decimal_scaled::I128s12;
// exp2(0) == 1 (f64::exp2(0.0) == 1.0 exactly).
assert_eq!(I128s12::ZERO.exp2(), I128s12::ONE);Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub const fn checked_add(self, rhs: Self) -> Option<Self>
pub const fn checked_add(self, rhs: Self) -> Option<Self>
Returns self + rhs, or None if the result overflows i128.
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(1_000_000_000_000); // 1.0
let b = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(a.checked_add(b), Some(I128s12::from_bits(3_000_000_000_000)));
assert_eq!(I128s12::MAX.checked_add(I128s12::ONE), None);Sourcepub const fn wrapping_add(self, rhs: Self) -> Self
pub const fn wrapping_add(self, rhs: Self) -> Self
Returns self + rhs with two’s-complement wrap on overflow.
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(1_000_000_000_000); // 1.0
let b = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(a.wrapping_add(b), I128s12::from_bits(3_000_000_000_000));
// Overflow wraps to MIN.
assert_eq!(I128s12::MAX.wrapping_add(I128s12::from_bits(1)), I128s12::MIN);Sourcepub const fn saturating_add(self, rhs: Self) -> Self
pub const fn saturating_add(self, rhs: Self) -> Self
Returns self + rhs, clamped to I128::MAX or I128::MIN on overflow.
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(1_000_000_000_000); // 1.0
let b = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(a.saturating_add(b), I128s12::from_bits(3_000_000_000_000));
assert_eq!(I128s12::MAX.saturating_add(I128s12::ONE), I128s12::MAX);
assert_eq!(I128s12::MIN.saturating_add(-I128s12::ONE), I128s12::MIN);Sourcepub const fn overflowing_add(self, rhs: Self) -> (Self, bool)
pub const fn overflowing_add(self, rhs: Self) -> (Self, bool)
Returns (self + rhs, did_overflow) where the value is the
two’s-complement wrapping result.
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(1_000_000_000_000); // 1.0
let b = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(a.overflowing_add(b), (I128s12::from_bits(3_000_000_000_000), false));
assert_eq!(
I128s12::MAX.overflowing_add(I128s12::from_bits(1)),
(I128s12::MIN, true),
);Sourcepub const fn checked_sub(self, rhs: Self) -> Option<Self>
pub const fn checked_sub(self, rhs: Self) -> Option<Self>
Returns self - rhs, or None if the result overflows i128.
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
let three = I128s12::from_bits(3_000_000_000_000);
let two = I128s12::from_bits(2_000_000_000_000);
assert_eq!(three.checked_sub(two), Some(I128s12::ONE));
assert_eq!(I128s12::MIN.checked_sub(I128s12::ONE), None);Sourcepub const fn wrapping_sub(self, rhs: Self) -> Self
pub const fn wrapping_sub(self, rhs: Self) -> Self
Returns self - rhs with two’s-complement wrap on overflow.
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
let three = I128s12::from_bits(3_000_000_000_000);
let two = I128s12::from_bits(2_000_000_000_000);
assert_eq!(three.wrapping_sub(two), I128s12::ONE);
// Underflow wraps to MAX.
assert_eq!(I128s12::MIN.wrapping_sub(I128s12::from_bits(1)), I128s12::MAX);Sourcepub const fn saturating_sub(self, rhs: Self) -> Self
pub const fn saturating_sub(self, rhs: Self) -> Self
Returns self - rhs, clamped to I128::MAX or I128::MIN on overflow.
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
let three = I128s12::from_bits(3_000_000_000_000);
let two = I128s12::from_bits(2_000_000_000_000);
assert_eq!(three.saturating_sub(two), I128s12::ONE);
assert_eq!(I128s12::MIN.saturating_sub(I128s12::ONE), I128s12::MIN);Sourcepub const fn overflowing_sub(self, rhs: Self) -> (Self, bool)
pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool)
Returns (self - rhs, did_overflow) where the value is the
two’s-complement wrapping result.
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
let three = I128s12::from_bits(3_000_000_000_000);
let two = I128s12::from_bits(2_000_000_000_000);
assert_eq!(three.overflowing_sub(two), (I128s12::ONE, false));
assert_eq!(
I128s12::MIN.overflowing_sub(I128s12::from_bits(1)),
(I128s12::MAX, true),
);Sourcepub const fn checked_neg(self) -> Option<Self>
pub const fn checked_neg(self) -> Option<Self>
Returns -self, or None for I128::MIN (whose two’s-complement
negation does not fit in i128).
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::ONE.checked_neg(), Some(-I128s12::ONE));
assert_eq!(I128s12::MIN.checked_neg(), None);Sourcepub const fn wrapping_neg(self) -> Self
pub const fn wrapping_neg(self) -> Self
Returns -self with two’s-complement wrap. For I128::MIN
this returns I128::MIN (matches i128::wrapping_neg).
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::ONE.wrapping_neg(), -I128s12::ONE);
assert_eq!(I128s12::MIN.wrapping_neg(), I128s12::MIN);Sourcepub const fn saturating_neg(self) -> Self
pub const fn saturating_neg(self) -> Self
Returns -self, clamped to I128::MAX for I128::MIN
(matches i128::saturating_neg).
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::ONE.saturating_neg(), -I128s12::ONE);
assert_eq!(I128s12::MIN.saturating_neg(), I128s12::MAX);Sourcepub const fn overflowing_neg(self) -> (Self, bool)
pub const fn overflowing_neg(self) -> (Self, bool)
Returns (-self, did_overflow). Overflow occurs only for
I128::MIN, in which case the wrapping result is I128::MIN.
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::ONE.overflowing_neg(), (-I128s12::ONE, false));
assert_eq!(I128s12::MIN.overflowing_neg(), (I128s12::MIN, true));Sourcepub fn checked_mul(self, rhs: Self) -> Option<Self>
pub fn checked_mul(self, rhs: Self) -> Option<Self>
Returns self * rhs, or None if the rescaled product does not
fit in i128.
The intermediate product is computed with 256-bit arithmetic and
cannot itself overflow. The only failure mode is a final i128
quotient that exceeds the storage range.
§Precision
Strict: the result is truncated (not rounded) toward zero during
the scale-restoring divide, identical to the default * operator.
§Examples
use decimal_scaled::I128s12;
let half = I128s12::from_bits(500_000_000_000); // 0.5
assert_eq!(half.checked_mul(half), Some(I128s12::from_bits(250_000_000_000)));
assert_eq!(I128s12::MAX.checked_mul(I128s12::from_bits(2_000_000_000_000)), None);Sourcepub fn wrapping_mul(self, rhs: Self) -> Self
pub fn wrapping_mul(self, rhs: Self) -> Self
Returns self * rhs with two’s-complement wrap when the rescaled
product does not fit in i128.
On overflow, falls back to (a.wrapping_mul(b)).wrapping_div(multiplier()).
The exact bit pattern of the wrapping result at extreme magnitudes
is an implementation detail; only the no-panic contract is guaranteed.
§Precision
Strict: truncates toward zero during the scale-restoring divide.
§Examples
use decimal_scaled::I128s12;
let half = I128s12::from_bits(500_000_000_000); // 0.5
assert_eq!(half.wrapping_mul(half), I128s12::from_bits(250_000_000_000));
// Overflow does not panic.
let _ = I128s12::MAX.wrapping_mul(I128s12::from_bits(2_000_000_000_000));Sourcepub fn saturating_mul(self, rhs: Self) -> Self
pub fn saturating_mul(self, rhs: Self) -> Self
Returns self * rhs, clamped to I128::MAX or I128::MIN on overflow.
The clamp direction is determined by the XOR of operand signs:
same-sign operands saturate to MAX; mixed-sign operands saturate
to MIN.
§Precision
Strict: truncates toward zero during the scale-restoring divide.
§Examples
use decimal_scaled::I128s12;
let two = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(I128s12::MAX.saturating_mul(two), I128s12::MAX);
assert_eq!(I128s12::MAX.saturating_mul(-two), I128s12::MIN);Sourcepub fn overflowing_mul(self, rhs: Self) -> (Self, bool)
pub fn overflowing_mul(self, rhs: Self) -> (Self, bool)
Returns (self * rhs, did_overflow) where the value is the
wrapping result when overflow occurs.
§Precision
Strict: truncates toward zero during the scale-restoring divide.
§Examples
use decimal_scaled::I128s12;
let half = I128s12::from_bits(500_000_000_000); // 0.5
assert_eq!(half.overflowing_mul(half), (I128s12::from_bits(250_000_000_000), false));
let (_, ovf) = I128s12::MAX.overflowing_mul(I128s12::from_bits(2_000_000_000_000));
assert!(ovf);Sourcepub fn checked_div(self, rhs: Self) -> Option<Self>
pub fn checked_div(self, rhs: Self) -> Option<Self>
Returns self / rhs, or None on division by zero or if the
rescaled quotient does not fit in i128.
The only finite-operand overflow case is
I128::MIN / NEG_ONE (storage negation of i128::MIN overflows).
§Precision
Strict: the widening divide truncates toward zero, identical to
the default / operator.
§Examples
use decimal_scaled::I128s12;
let six = I128s12::from_bits(6_000_000_000_000); // 6.0
let two = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(six.checked_div(two), Some(I128s12::from_bits(3_000_000_000_000)));
assert_eq!(I128s12::ONE.checked_div(I128s12::ZERO), None);Sourcepub fn wrapping_div(self, rhs: Self) -> Self
pub fn wrapping_div(self, rhs: Self) -> Self
Returns self / rhs with two’s-complement wrap when the rescaled
quotient does not fit in i128.
On overflow, falls back to
(a.wrapping_mul(multiplier())).wrapping_div(b).
§Precision
Strict: truncates toward zero.
§Panics
Panics on rhs == ZERO (matches i128::wrapping_div).
§Examples
use decimal_scaled::I128s12;
let six = I128s12::from_bits(6_000_000_000_000); // 6.0
let two = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(six.wrapping_div(two), I128s12::from_bits(3_000_000_000_000));Sourcepub fn saturating_div(self, rhs: Self) -> Self
pub fn saturating_div(self, rhs: Self) -> Self
Returns self / rhs, clamped to I128::MAX or I128::MIN on
overflow.
The clamp direction is determined by the XOR of operand signs, because the scale multiplier is always positive.
§Precision
Strict: truncates toward zero.
§Panics
Panics on rhs == ZERO (matches i128::saturating_div).
§Examples
use decimal_scaled::I128s12;
let six = I128s12::from_bits(6_000_000_000_000); // 6.0
let two = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(six.saturating_div(two), I128s12::from_bits(3_000_000_000_000));
// MAX / 0.5 overflows; both positive so clamp to MAX.
assert_eq!(I128s12::MAX.saturating_div(I128s12::from_bits(500_000_000_000)), I128s12::MAX);Sourcepub fn overflowing_div(self, rhs: Self) -> (Self, bool)
pub fn overflowing_div(self, rhs: Self) -> (Self, bool)
Returns (self / rhs, did_overflow) where the value is the
wrapping result when overflow occurs.
§Precision
Strict: truncates toward zero.
§Panics
Panics on rhs == ZERO (matches i128::overflowing_div).
§Examples
use decimal_scaled::I128s12;
let six = I128s12::from_bits(6_000_000_000_000); // 6.0
let two = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(six.overflowing_div(two), (I128s12::from_bits(3_000_000_000_000), false));
let half = I128s12::from_bits(500_000_000_000); // 0.5
let (_, ovf) = I128s12::MAX.overflowing_div(half);
assert!(ovf);Sourcepub const fn checked_rem(self, rhs: Self) -> Option<Self>
pub const fn checked_rem(self, rhs: Self) -> Option<Self>
Returns self % rhs, or None on rhs == ZERO or for the
storage-level overflow case I128::MIN % from_bits(-1)
(matches i128::checked_rem).
§Precision
Strict: operates on integer raw storage with no rounding.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(5_500_000_000_000); // 5.5
let two = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(a.checked_rem(two), Some(I128s12::from_bits(1_500_000_000_000)));
assert_eq!(I128s12::ONE.checked_rem(I128s12::ZERO), None);Sourcepub const fn wrapping_rem(self, rhs: Self) -> Self
pub const fn wrapping_rem(self, rhs: Self) -> Self
Returns self % rhs. For the storage-level overflow case
I128::MIN.wrapping_rem(from_bits(-1)), returns ZERO
(matches i128::wrapping_rem).
§Precision
Strict: operates on integer raw storage with no rounding.
§Panics
Panics on rhs == ZERO (matches i128::wrapping_rem).
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(5_500_000_000_000); // 5.5
let two = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(a.wrapping_rem(two), I128s12::from_bits(1_500_000_000_000));Sourcepub const fn overflowing_rem(self, rhs: Self) -> (Self, bool)
pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool)
Returns (self % rhs, did_overflow). Overflow (did_overflow == true)
occurs only for the storage-level case I128::MIN % from_bits(-1),
in which case the wrapping result is ZERO.
§Precision
Strict: operates on integer raw storage with no rounding.
§Panics
Panics on rhs == ZERO (matches i128::overflowing_rem).
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(5_500_000_000_000); // 5.5
let two = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!(a.overflowing_rem(two), (I128s12::from_bits(1_500_000_000_000), false));
let neg_one_lsb = I128s12::from_bits(-1);
assert_eq!(I128s12::MIN.overflowing_rem(neg_one_lsb), (I128s12::ZERO, true));Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub fn pow(self, exp: u32) -> Self
pub fn pow(self, exp: u32) -> Self
Raises self to the power exp.
Uses square-and-multiply: walks the bits of exp from low to
high, squaring the base each step and accumulating when the
corresponding bit is set. Costs O(log exp) multiplications.
Each multiplication routes through the I128 Mul operator.
exp = 0 always returns ONE, even when self is ZERO
(matches i128::pow convention).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Panics
In debug builds, panics on i128 overflow at any multiplication
step. In release builds, wraps two’s-complement. Matches
i128::pow and I128::Mul semantics.
Use Self::checked_pow, Self::wrapping_pow,
Self::saturating_pow, or Self::overflowing_pow for
explicit overflow control.
§Examples
use decimal_scaled::I128s12;
let two = I128s12::from_int(2);
assert_eq!(two.pow(10), I128s12::from_int(1024));
// exp = 0 returns ONE regardless of base.
assert_eq!(I128s12::ZERO.pow(0), I128s12::ONE);Sourcepub fn powi(self, exp: i32) -> Self
pub fn powi(self, exp: i32) -> Self
Raises self to the signed integer power exp.
For non-negative exp, equivalent to self.pow(exp as u32).
For negative exp, returns I128::ONE / self.pow(exp.unsigned_abs()),
i.e. the reciprocal of the positive-exponent form.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Panics
- Overflow of
i128storage at any step in debug builds (matchesSelf::pow). - Division by zero when
self == ZEROandexp < 0.
§Examples
use decimal_scaled::I128s12;
let two = I128s12::from_int(2);
assert_eq!(two.powi(-1), I128s12::ONE / two);
assert_eq!(two.powi(0), I128s12::ONE);
assert_eq!(two.powi(3), I128s12::from_int(8));Sourcepub fn powf(self, exp: I128<SCALE>) -> Self
pub fn powf(self, exp: I128<SCALE>) -> Self
Raises self to the power exp via the f64 bridge.
Converts both operands to f64, calls f64::powf, then converts
the result back. For integer exponents, prefer Self::pow or
Self::powi, which are bit-exact.
NaN results map to ZERO; infinities clamp to MAX or MIN,
following the saturate-vs-error policy of Self::from_f64_lossy.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
let two = I128s12::from_int(2);
let three = I128s12::from_int(3);
// 2^3 = 8, within f64 precision.
assert!((two.powf(three).to_f64_lossy() - 8.0).abs() < 1e-9);Sourcepub fn sqrt(self) -> Self
pub fn sqrt(self) -> Self
Returns the square root of self via the f64 bridge.
IEEE 754 mandates that f64::sqrt is correctly-rounded
(round-to-nearest, ties-to-even). Combined with the deterministic
to_f64_lossy / from_f64_lossy round-trip, this makes
I128::sqrt bit-deterministic: the same input produces the same
output bit-pattern on every IEEE-754-conformant platform.
Negative inputs produce a NaN from f64::sqrt, which
Self::from_f64_lossy maps to ZERO per the saturate-vs-error
policy. No panic is raised for negative inputs.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::ZERO.sqrt(), I128s12::ZERO);
// f64::sqrt(1.0) == 1.0 exactly, so the result is bit-exact.
assert_eq!(I128s12::ONE.sqrt(), I128s12::ONE);Sourcepub fn cbrt(self) -> Self
pub fn cbrt(self) -> Self
Returns the cube root of self via the f64 bridge.
f64::cbrt is defined for the entire real line, including
negative inputs (cbrt(-8.0) == -2.0). The result is
bit-deterministic across IEEE-754-conformant platforms because
f64::cbrt is correctly-rounded.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
let neg_eight = I128s12::from_int(-8);
let result = neg_eight.cbrt();
assert!((result.to_f64_lossy() - (-2.0_f64)).abs() < 1e-9);Sourcepub fn mul_add(self, a: Self, b: Self) -> Self
pub fn mul_add(self, a: Self, b: Self) -> Self
Returns self * a + b.
Mirrors the f64::mul_add call shape so f64-generic numeric code
can monomorphise to I128 without rewriting call sites. No
hardware FMA is involved; the multiply uses the I128 Mul
operator and the add uses plain i128 addition.
The result is bit-equal to self * a + b on every input,
including panic or wrap behaviour at overflow boundaries.
Available in no_std builds because the underlying Mul and
Add operators require only core.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Panics
In debug builds, panics on overflow at the multiply step or the add step. In release builds, both steps wrap two’s-complement.
§Examples
use decimal_scaled::I128s12;
let two = I128s12::from_int(2);
let three = I128s12::from_int(3);
let four = I128s12::from_int(4);
// 2 * 3 + 4 = 10
assert_eq!(two.mul_add(three, four), I128s12::from_int(10));Sourcepub fn hypot(self, other: Self) -> Self
pub fn hypot(self, other: Self) -> Self
Returns sqrt(self^2 + other^2) without intermediate overflow.
The naive form (self * self + other * other).sqrt() overflows
i128 once either operand approaches sqrt(I128::MAX). This
method uses the scale trick to avoid that:
hypot(a, b) = max(|a|, |b|) * sqrt(1 + (min(|a|, |b|) / max(|a|, |b|))^2)The min/max ratio is in [0, 1], so ratio^2 is also in
[0, 1] and cannot overflow. The outer multiply by large only
overflows when the true hypotenuse genuinely exceeds I128::MAX,
which matches f64::hypot’s contract.
Both inputs are absolute-valued before processing, so
hypot(-a, b) == hypot(a, b).
Edge cases: hypot(0, 0) == 0 (bit-exact via the early return);
hypot(0, x) ~= |x| and hypot(x, 0) ~= |x|.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
let three = I128s12::from_int(3);
let four = I128s12::from_int(4);
// Pythagorean triple: hypot(3, 4) ~= 5.
assert!((three.hypot(four).to_f64_lossy() - 5.0).abs() < 1e-9);Sourcepub fn checked_pow(self, exp: u32) -> Option<Self>
pub fn checked_pow(self, exp: u32) -> Option<Self>
Returns Some(self^exp), or None if any multiplication step
overflows i128.
Walks the same square-and-multiply as Self::pow but uses
mul_div_pow10 (which returns Option<i128>) at each step.
The first None short-circuits to a None return.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
// MAX^2 overflows.
assert!(I128s12::MAX.checked_pow(2).is_none());
// Any power of ONE is ONE.
assert_eq!(I128s12::ONE.checked_pow(1_000_000), Some(I128s12::ONE));Sourcepub fn wrapping_pow(self, exp: u32) -> Self
pub fn wrapping_pow(self, exp: u32) -> Self
Returns self^exp, wrapping two’s-complement on overflow at
every multiplication step.
Follows the same square-and-multiply structure as Self::pow.
When a step overflows mul_div_pow10, the fallback is
wrapping_mul followed by wrapping_div of the scale
multiplier. The exact wrap pattern is deterministic and
reproducible but is not otherwise specified.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
// ONE^N never overflows and returns ONE.
assert_eq!(I128s12::ONE.wrapping_pow(1_000_000), I128s12::ONE);
// MAX^2 wraps to a deterministic but unspecified value.
let _ = I128s12::MAX.wrapping_pow(2);Sourcepub fn saturating_pow(self, exp: u32) -> Self
pub fn saturating_pow(self, exp: u32) -> Self
Returns self^exp, clamping to I128::MAX or I128::MIN on
overflow at any step.
On the first step that overflows, the result is clamped based on
the sign of the mathematical result: positive overflows clamp to
MAX, negative overflows clamp to MIN. The sign of the result
is determined by self.signum() and whether exp is odd.
exp = 0 always returns ONE before entering the loop.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::MAX.saturating_pow(2), I128s12::MAX);
assert_eq!(I128s12::ONE.saturating_pow(1_000_000), I128s12::ONE);Sourcepub fn overflowing_pow(self, exp: u32) -> (Self, bool)
pub fn overflowing_pow(self, exp: u32) -> (Self, bool)
Returns (self^exp, overflowed).
overflowed is true if any multiplication step overflowed
i128. The returned value is the wrapping form (matches
Self::wrapping_pow).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let (_value, overflowed) = I128s12::MAX.overflowing_pow(2);
assert!(overflowed);
let (value, overflowed) = I128s12::ONE.overflowing_pow(5);
assert!(!overflowed);
assert_eq!(value, I128s12::ONE);Source§impl<const SCALE: u32> I128<SCALE>
impl<const SCALE: u32> I128<SCALE>
Sourcepub fn tan(self) -> Self
pub fn tan(self) -> Self
Tangent of self, where self is in radians.
f64::tan returns very large magnitudes near odd multiples of
pi/2 and infinity at the limit. Inputs that drive the f64
result outside [I128::MIN, I128::MAX] saturate per
Self::from_f64_lossy.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// tan(0) == 0 (bit-exact: f64::tan(0.0) == 0.0).
assert_eq!(I128s12::ZERO.tan(), I128s12::ZERO);Sourcepub fn asin(self) -> Self
pub fn asin(self) -> Self
Arcsine of self. Returns radians in [-pi/2, pi/2].
f64::asin returns NaN for inputs outside [-1, 1], which
Self::from_f64_lossy maps to I128::ZERO.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// asin(0) == 0.
assert_eq!(I128s12::ZERO.asin(), I128s12::ZERO);Sourcepub fn acos(self) -> Self
pub fn acos(self) -> Self
Arccosine of self. Returns radians in [0, pi].
f64::acos returns NaN for inputs outside [-1, 1], which
Self::from_f64_lossy maps to I128::ZERO.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::{I128s12, DecimalConsts};
// acos(1) == 0.
assert_eq!(I128s12::ONE.acos(), I128s12::ZERO);Sourcepub fn atan2(self, other: Self) -> Self
pub fn atan2(self, other: Self) -> Self
Four-quadrant arctangent of self (y) over other (x).
Returns radians in (-pi, pi].
Signature matches f64::atan2(self, other): the receiver is
y and the argument is x.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::{I128s12, DecimalConsts};
// atan2(1, 1) ~= pi/4 (45 degrees, first quadrant).
let one = I128s12::ONE;
let result = one.atan2(one); // approximately I128s12::quarter_pi()Sourcepub fn sinh(self) -> Self
pub fn sinh(self) -> Self
Hyperbolic sine of self.
Defined for the entire real line. Saturates at large magnitudes
per Self::from_f64_lossy.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// sinh(0) == 0.
assert_eq!(I128s12::ZERO.sinh(), I128s12::ZERO);Sourcepub fn cosh(self) -> Self
pub fn cosh(self) -> Self
Hyperbolic cosine of self.
Defined for the entire real line; result is always >= 1.
Saturates at large magnitudes per Self::from_f64_lossy.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// cosh(0) == 1.
assert_eq!(I128s12::ZERO.cosh(), I128s12::ONE);Sourcepub fn acosh(self) -> Self
pub fn acosh(self) -> Self
Inverse hyperbolic cosine of self.
f64::acosh returns NaN for inputs less than 1, which
Self::from_f64_lossy maps to I128::ZERO.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// acosh(1) == 0.
assert_eq!(I128s12::ONE.acosh(), I128s12::ZERO);Sourcepub fn atanh(self) -> Self
pub fn atanh(self) -> Self
Inverse hyperbolic tangent of self.
f64::atanh returns NaN for inputs outside (-1, 1), which
Self::from_f64_lossy maps to I128::ZERO.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// atanh(0) == 0.
assert_eq!(I128s12::ZERO.atanh(), I128s12::ZERO);Sourcepub fn to_degrees(self) -> Self
pub fn to_degrees(self) -> Self
Convert radians to degrees: self * (180 / pi).
Routed through f64::to_degrees so results match the de facto
reference produced by the rest of the Rust ecosystem. Multiplying
by a precomputed I128 factor derived from I128::pi() would
diverge from f64 by a 1-LSB rescale rounding without any
practical determinism gain, since the f64 bridge is already the
precision floor.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// to_degrees(0) == 0.
assert_eq!(I128s12::ZERO.to_degrees(), I128s12::ZERO);Sourcepub fn to_radians(self) -> Self
pub fn to_radians(self) -> Self
Convert degrees to radians: self * (pi / 180).
Routed through f64::to_radians. See Self::to_degrees for
the rationale.
§Precision
Lossy: involves f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
// to_radians(0) == 0.
assert_eq!(I128s12::ZERO.to_radians(), I128s12::ZERO);Trait Implementations§
Source§impl<const SCALE: u32> Add for I128<SCALE>
impl<const SCALE: u32> Add for I128<SCALE>
Source§fn add(self, rhs: Self) -> Self
fn add(self, rhs: Self) -> Self
Add two values of the same scale.
Because both operands are in value * 10^S form, the raw storage
values can be added directly with no rescaling.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(1_500_000_000_000); // 1.5
let b = I128s12::from_bits(2_500_000_000_000); // 2.5
assert_eq!((a + b).to_bits(), 4_000_000_000_000);Source§impl<const SCALE: u32> Binary for I128<SCALE>
impl<const SCALE: u32> Binary for I128<SCALE>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats the raw i128 storage in binary.
See fmt::LowerHex for the storage-versus-value distinction.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
// 10^12 in binary is a 40-bit value.
let s = format!("{:b}", I128s12::ONE);
assert_eq!(s, "1110100011010100101001010001000000000000");Source§impl<const SCALE: u32> BitAnd for I128<SCALE>
impl<const SCALE: u32> BitAnd for I128<SCALE>
Source§fn bitand(self, rhs: Self) -> Self
fn bitand(self, rhs: Self) -> Self
Bitwise AND of the underlying i128 storage values.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(0b1100);
let b = I128s12::from_bits(0b1010);
assert_eq!(a & b, I128s12::from_bits(0b1000));Source§impl<const SCALE: u32> BitAndAssign for I128<SCALE>
impl<const SCALE: u32> BitAndAssign for I128<SCALE>
Source§fn bitand_assign(&mut self, rhs: Self)
fn bitand_assign(&mut self, rhs: Self)
In-place bitwise AND of the underlying i128 storage.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> BitOr for I128<SCALE>
impl<const SCALE: u32> BitOr for I128<SCALE>
Source§fn bitor(self, rhs: Self) -> Self
fn bitor(self, rhs: Self) -> Self
Bitwise OR of the underlying i128 storage values.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(0b1100);
let b = I128s12::from_bits(0b1010);
assert_eq!(a | b, I128s12::from_bits(0b1110));Source§impl<const SCALE: u32> BitOrAssign for I128<SCALE>
impl<const SCALE: u32> BitOrAssign for I128<SCALE>
Source§fn bitor_assign(&mut self, rhs: Self)
fn bitor_assign(&mut self, rhs: Self)
In-place bitwise OR of the underlying i128 storage.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> BitXor for I128<SCALE>
impl<const SCALE: u32> BitXor for I128<SCALE>
Source§fn bitxor(self, rhs: Self) -> Self
fn bitxor(self, rhs: Self) -> Self
Bitwise XOR of the underlying i128 storage values.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(0b1100);
let b = I128s12::from_bits(0b1010);
assert_eq!(a ^ b, I128s12::from_bits(0b0110));Source§impl<const SCALE: u32> BitXorAssign for I128<SCALE>
impl<const SCALE: u32> BitXorAssign for I128<SCALE>
Source§fn bitxor_assign(&mut self, rhs: Self)
fn bitxor_assign(&mut self, rhs: Self)
In-place bitwise XOR of the underlying i128 storage.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> Bounded for I128<SCALE>
impl<const SCALE: u32> Bounded for I128<SCALE>
Source§impl<const SCALE: u32> CheckedAdd for I128<SCALE>
impl<const SCALE: u32> CheckedAdd for I128<SCALE>
Source§fn checked_add(&self, rhs: &Self) -> Option<Self>
fn checked_add(&self, rhs: &Self) -> Option<Self>
Adds rhs to self, returning None on overflow.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::CheckedAdd;
let two = I128s12::from_bits(2_000_000_000_000);
assert_eq!(I128s12::ONE.checked_add(I128s12::ONE), Some(two));
assert_eq!(I128s12::MAX.checked_add(I128s12::ONE), None);Source§impl<const SCALE: u32> CheckedDiv for I128<SCALE>
impl<const SCALE: u32> CheckedDiv for I128<SCALE>
Source§fn checked_div(&self, v: &Self) -> Option<Self>
fn checked_div(&self, v: &Self) -> Option<Self>
Divides self by v, returning None on division by zero or overflow.
Delegates to the inherent I128::checked_div method, which uses a
256-bit widening divide. Returns None on division by zero or when the
result overflows i128 (the only case is I128::MIN / -ONE). The
trait and inherent paths are bit-identical.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::CheckedDiv;
let half = I128s12::from_bits(500_000_000_000);
let two = I128s12::from_bits(2_000_000_000_000);
let quarter = I128s12::from_bits(250_000_000_000);
assert_eq!(half.checked_div(two), Some(quarter));
assert_eq!(I128s12::ONE.checked_div(I128s12::ZERO), None);Source§impl<const SCALE: u32> CheckedMul for I128<SCALE>
impl<const SCALE: u32> CheckedMul for I128<SCALE>
Source§fn checked_mul(&self, v: &Self) -> Option<Self>
fn checked_mul(&self, v: &Self) -> Option<Self>
Multiplies self by v, returning None when the result overflows i128.
Delegates to the inherent I128::checked_mul method, which uses a
256-bit intermediate product so that only the final result needs to
fit in i128. Returns None only when the quotient after rescaling
overflows. The trait and inherent paths are bit-identical.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::CheckedMul;
let half = I128s12::from_bits(500_000_000_000);
let quarter = I128s12::from_bits(250_000_000_000);
assert_eq!(half.checked_mul(half), Some(quarter));
let two = I128s12::from_bits(2_000_000_000_000);
assert_eq!(I128s12::MAX.checked_mul(two), None);Source§impl<const SCALE: u32> CheckedNeg for I128<SCALE>
impl<const SCALE: u32> CheckedNeg for I128<SCALE>
Source§fn checked_neg(&self) -> Option<Self>
fn checked_neg(&self) -> Option<Self>
Negates self, returning None for I128::MIN.
i128::MIN has no positive counterpart in two’s-complement, so
negating it overflows. All other values succeed.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::CheckedNeg;
assert_eq!(I128s12::ONE.checked_neg(), Some(-I128s12::ONE));
assert_eq!(I128s12::ZERO.checked_neg(), Some(I128s12::ZERO));
assert_eq!(I128s12::MIN.checked_neg(), None);Source§impl<const SCALE: u32> CheckedRem for I128<SCALE>
impl<const SCALE: u32> CheckedRem for I128<SCALE>
Source§fn checked_rem(&self, rhs: &Self) -> Option<Self>
fn checked_rem(&self, rhs: &Self) -> Option<Self>
Computes self % rhs, returning None when rhs is zero.
Because both operands share the same SCALE, no rescaling is needed.
Delegates directly to i128::checked_rem.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::CheckedRem;
let a = I128s12::from_bits(5_500_000_000_000); // 5.5
let b = I128s12::from_bits(2_000_000_000_000); // 2.0
let expected = I128s12::from_bits(1_500_000_000_000); // 1.5
assert_eq!(a.checked_rem(b), Some(expected));
assert_eq!(a.checked_rem(I128s12::ZERO), None);Source§impl<const SCALE: u32> CheckedSub for I128<SCALE>
impl<const SCALE: u32> CheckedSub for I128<SCALE>
Source§fn checked_sub(&self, rhs: &Self) -> Option<Self>
fn checked_sub(&self, rhs: &Self) -> Option<Self>
Subtracts rhs from self, returning None on underflow.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::CheckedSub;
let three = I128s12::from_bits(3_000_000_000_000);
let two = I128s12::from_bits(2_000_000_000_000);
assert_eq!(three.checked_sub(two), Some(I128s12::ONE));
assert_eq!(I128s12::MIN.checked_sub(I128s12::ONE), None);Source§impl<const SCALE: u32> Debug for I128<SCALE>
impl<const SCALE: u32> Debug for I128<SCALE>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats as I128<SCALE>(<canonical decimal>).
Delegates to fmt::Display so the output shows the human-readable
decimal value rather than the raw i128 storage.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let v = I128s12::from_bits(1_500_000_000_000);
assert_eq!(format!("{v:?}"), "I128<12>(1.500000000000)");Source§impl<const SCALE: u32> DecimalConsts for I128<SCALE>
impl<const SCALE: u32> DecimalConsts for I128<SCALE>
Source§fn quarter_pi() -> Self
fn quarter_pi() -> Self
Source§impl<const SCALE: u32> Default for I128<SCALE>
Default returns ZERO, matching i128::default() == 0.
impl<const SCALE: u32> Default for I128<SCALE>
Default returns ZERO, matching i128::default() == 0.
This lets #[derive(Default)] work correctly on structs that contain
I128<S> fields.
Source§impl<'de, const SCALE: u32> Deserialize<'de> for I128<SCALE>
impl<'de, const SCALE: u32> Deserialize<'de> for I128<SCALE>
Source§fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
Deserialise from a base-10 integer string (human-readable formats), 16 little-endian bytes (binary formats), or a native integer (self-describing binary formats such as CBOR).
Human-readable formats route via deserialize_any so a JSON
string, JSON number, or TOML integer all reach the correct
visitor branch. Binary formats that are not self-describing
(postcard, bincode) route via deserialize_bytes directly.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> Display for I128<SCALE>
impl<const SCALE: u32> Display for I128<SCALE>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats the value as a canonical decimal string.
Always emits exactly SCALE fractional digits. The integer and
fractional parts are derived from integer division of the unsigned
magnitude, so i128::MIN (whose absolute value overflows i128)
is handled correctly via unsigned_abs.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let v = I128s12::from_bits(1_500_000_000_000);
assert_eq!(v.to_string(), "1.500000000000");
let neg = I128s12::from_bits(-1_500_000_000_000);
assert_eq!(neg.to_string(), "-1.500000000000");Source§impl<const SCALE: u32> Div for I128<SCALE>
impl<const SCALE: u32> Div for I128<SCALE>
Source§fn div(self, rhs: Self) -> Self
fn div(self, rhs: Self) -> Self
Divide self by rhs, rescaling the numerator to keep the result
in value * 10^S form.
The numerator self.0 is widened to 256 bits and multiplied by
10^SCALE before dividing by rhs.0. This avoids the intermediate
overflow that would occur with a naive (self.0 * 10^S) / rhs.0
approach at large dividend magnitudes.
§Panics
Panics on division by zero (matching i128 /). Also panics in debug
builds when the final quotient overflows i128; wraps in release
builds.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(3_000_000_000_000); // 3.0
let b = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!((a / b).to_bits(), 1_500_000_000_000); // 1.5Source§impl<const SCALE: u32> DivAssign for I128<SCALE>
impl<const SCALE: u32> DivAssign for I128<SCALE>
Source§fn div_assign(&mut self, rhs: Self)
fn div_assign(&mut self, rhs: Self)
Divide self by rhs in place.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> From<i64> for I128<SCALE>
impl<const SCALE: u32> From<i64> for I128<SCALE>
Source§fn from(value: i64) -> Self
fn from(value: i64) -> Self
Converts value by scaling it to value * 10^SCALE.
Lossless for all SCALE < 19. At SCALE = 12 all i64 values
fit with roughly six orders of magnitude of headroom before
i128::MAX.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from(1_i64).to_bits(), 1_000_000_000_000);
assert_eq!(I128s12::from(-1_i64).to_bits(), -1_000_000_000_000);Source§impl<const SCALE: u32> From<i8> for I128<SCALE>
impl<const SCALE: u32> From<i8> for I128<SCALE>
Source§fn from(value: i8) -> Self
fn from(value: i8) -> Self
Converts value by scaling it to value * 10^SCALE.
Lossless for all SCALE < 36 (since i8::MAX * 10^36 < i128::MAX).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from(1_i8).to_bits(), 1_000_000_000_000);
assert_eq!(I128s12::from(-1_i8).to_bits(), -1_000_000_000_000);Source§impl<const SCALE: u32> From<u64> for I128<SCALE>
impl<const SCALE: u32> From<u64> for I128<SCALE>
Source§fn from(value: u64) -> Self
fn from(value: u64) -> Self
Converts value by scaling it to value * 10^SCALE.
Lossless for all SCALE < 19. At SCALE = 12 the worst-case
product is u64::MAX * 10^12 (~1.8e31), well under i128::MAX
(~1.7e38).
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from(1_u64).to_bits(), 1_000_000_000_000);Source§impl<const SCALE: u32> FromPrimitive for I128<SCALE>
impl<const SCALE: u32> FromPrimitive for I128<SCALE>
Source§fn from_i64(n: i64) -> Option<Self>
fn from_i64(n: i64) -> Option<Self>
Constructs a I128<SCALE> from an i64 integer value.
Scales n by 10^SCALE. Returns None when the multiplication
overflows i128, which can occur at pathologically large scale
values. At SCALE <= 18 the call always succeeds for any i64.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::FromPrimitive;
assert_eq!(I128s12::from_i64(0), Some(I128s12::ZERO));
assert_eq!(I128s12::from_i64(1), Some(I128s12::ONE));
assert_eq!(I128s12::from_i64(-42), Some(I128s12::from_bits(-42_000_000_000_000)));Source§fn from_u64(n: u64) -> Option<Self>
fn from_u64(n: u64) -> Option<Self>
Constructs a I128<SCALE> from a u64 integer value.
Scales n by 10^SCALE. Returns None on overflow. At
SCALE <= 18 the call always succeeds for any u64.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::FromPrimitive;
assert_eq!(I128s12::from_u64(0), Some(I128s12::ZERO));
assert_eq!(I128s12::from_u64(42), Some(I128s12::from_bits(42_000_000_000_000)));Source§fn from_i128(n: i128) -> Option<Self>
fn from_i128(n: i128) -> Option<Self>
Constructs a I128<SCALE> from an i128 integer value.
Returns None when scaling overflows. Delegates to the existing
TryFrom<i128> implementation.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::FromPrimitive;
assert_eq!(I128s12::from_i128(7), Some(I128s12::from_bits(7_000_000_000_000)));
assert_eq!(I128s12::from_i128(i128::MAX), None);Source§fn from_u128(n: u128) -> Option<Self>
fn from_u128(n: u128) -> Option<Self>
Constructs a I128<SCALE> from a u128 integer value.
Returns None when n > i128::MAX or when scaling overflows.
Delegates to the existing TryFrom<u128> implementation.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::FromPrimitive;
assert_eq!(I128s12::from_u128(99), Some(I128s12::from_bits(99_000_000_000_000)));
assert_eq!(I128s12::from_u128(u128::MAX), None);Source§fn from_f32(n: f32) -> Option<Self>
fn from_f32(n: f32) -> Option<Self>
Constructs a I128<SCALE> from an f32 value.
Returns None for NaN, infinities, or finite values whose
scaled representation overflows i128. Delegates to the existing
TryFrom<f32> implementation.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
use num_traits::FromPrimitive;
assert_eq!(I128s12::from_f32(0.0), Some(I128s12::ZERO));
assert_eq!(I128s12::from_f32(1.0), Some(I128s12::ONE));
assert_eq!(I128s12::from_f32(f32::NAN), None);
assert_eq!(I128s12::from_f32(f32::INFINITY), None);Source§fn from_f64(n: f64) -> Option<Self>
fn from_f64(n: f64) -> Option<Self>
Constructs a I128<SCALE> from an f64 value.
Returns None for NaN, infinities, or finite values whose
scaled representation overflows i128. Delegates to the existing
TryFrom<f64> implementation.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
use num_traits::FromPrimitive;
assert_eq!(I128s12::from_f64(0.0), Some(I128s12::ZERO));
assert_eq!(I128s12::from_f64(1.0), Some(I128s12::ONE));
assert_eq!(I128s12::from_f64(f64::NAN), None);
assert_eq!(I128s12::from_f64(1e30), None);Source§fn from_isize(n: isize) -> Option<Self>
fn from_isize(n: isize) -> Option<Self>
isize to return an optional value of this type. If the
value cannot be represented by this type, then None is returned.Source§fn from_i8(n: i8) -> Option<Self>
fn from_i8(n: i8) -> Option<Self>
i8 to return an optional value of this type. If the
value cannot be represented by this type, then None is returned.Source§fn from_i16(n: i16) -> Option<Self>
fn from_i16(n: i16) -> Option<Self>
i16 to return an optional value of this type. If the
value cannot be represented by this type, then None is returned.Source§fn from_i32(n: i32) -> Option<Self>
fn from_i32(n: i32) -> Option<Self>
i32 to return an optional value of this type. If the
value cannot be represented by this type, then None is returned.Source§fn from_usize(n: usize) -> Option<Self>
fn from_usize(n: usize) -> Option<Self>
usize to return an optional value of this type. If the
value cannot be represented by this type, then None is returned.Source§fn from_u8(n: u8) -> Option<Self>
fn from_u8(n: u8) -> Option<Self>
u8 to return an optional value of this type. If the
value cannot be represented by this type, then None is returned.Source§impl<const SCALE: u32> FromStr for I128<SCALE>
impl<const SCALE: u32> FromStr for I128<SCALE>
Source§fn from_str(s: &str) -> Result<Self, Self::Err>
fn from_str(s: &str) -> Result<Self, Self::Err>
Parses a canonical decimal literal into I128<SCALE>.
Delegates to the internal parser. See the module-level docs for the
full list of accepted and rejected forms, and ParseDecimalError
for the failure variants.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let v: I128s12 = "1.5".parse().unwrap();
assert_eq!(v.to_bits(), 1_500_000_000_000);
let neg: I128s12 = "-1.5".parse().unwrap();
assert_eq!(neg.to_bits(), -1_500_000_000_000);Source§type Err = ParseDecimalError
type Err = ParseDecimalError
Source§impl<const SCALE: u32> LowerExp for I128<SCALE>
impl<const SCALE: u32> LowerExp for I128<SCALE>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats the value in scientific notation with a lowercase e.
Trailing zeros in the mantissa are stripped, so 1.500000000000
formats as 1.5e0. Zero formats as 0e0.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let v = I128s12::from_bits(1_500_000_000_000);
assert_eq!(format!("{v:e}"), "1.5e0");
let sub = I128s12::from_bits(1_500_000_000);
assert_eq!(format!("{sub:e}"), "1.5e-3");Source§impl<const SCALE: u32> LowerHex for I128<SCALE>
impl<const SCALE: u32> LowerHex for I128<SCALE>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats the raw i128 storage (= value * 10^SCALE) as lowercase hex.
This is a bit-level view of the storage, not a hex encoding of the
decimal value. All standard format flags (#, 0, width, precision)
are forwarded to the underlying i128 formatter.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
// Storage for 1.0 at SCALE=12 is 10^12 = 0xe8d4a51000.
assert_eq!(format!("{:x}", I128s12::ONE), "e8d4a51000");Source§impl<const SCALE: u32> Mul for I128<SCALE>
impl<const SCALE: u32> Mul for I128<SCALE>
Source§fn mul(self, rhs: Self) -> Self
fn mul(self, rhs: Self) -> Self
Multiply two values, rescaling the result back to value * 10^S form.
The raw product a.0 * b.0 has units 10^(2S), so it must be
divided by 10^S to restore the canonical scale. This is done via
a 256-bit widening intermediate and a Moller-Granlund magic-number
divide (see the mg_divide module), which avoids the intermediate
overflow that would occur with a naive i128 multiply at large
operand magnitudes.
§Panics
Panics in debug builds when the final rescaled quotient overflows
i128::MAX. In release builds the result wraps two’s-complement.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(1_500_000_000_000); // 1.5
let b = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!((a * b).to_bits(), 3_000_000_000_000); // 3.0Source§impl<const SCALE: u32> MulAssign for I128<SCALE>
impl<const SCALE: u32> MulAssign for I128<SCALE>
Source§fn mul_assign(&mut self, rhs: Self)
fn mul_assign(&mut self, rhs: Self)
Multiply self by rhs in place.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> Neg for I128<SCALE>
impl<const SCALE: u32> Neg for I128<SCALE>
Source§fn neg(self) -> Self
fn neg(self) -> Self
Negate the value.
Negates the raw i128 storage directly; no rescaling needed.
§Panics
Panics in debug builds when self == I128::MIN because i128::MIN
has no positive counterpart in two’s-complement. In release builds
the result wraps to i128::MIN.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let x = I128s12::from_bits(1_500_000_000_000); // 1.5
assert_eq!((-x).to_bits(), -1_500_000_000_000);Source§impl<const SCALE: u32> Not for I128<SCALE>
impl<const SCALE: u32> Not for I128<SCALE>
Source§fn not(self) -> Self
fn not(self) -> Self
Bitwise complement of the underlying i128 storage (flip every
bit).
!I128::ZERO produces I128::from_bits(-1) (all-ones in two’s
complement).
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(!I128s12::ZERO, I128s12::from_bits(-1));
assert_eq!(!I128s12::from_bits(-1), I128s12::ZERO);Source§impl<const SCALE: u32> Num for I128<SCALE>
impl<const SCALE: u32> Num for I128<SCALE>
Source§fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>
fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>
Parses a decimal string in the given radix.
Only radix == 10 is supported; I128<SCALE> is a base-10 type
by construction. Any other radix returns ParseDecimalError::InvalidChar
without attempting to parse the string.
For radix == 10 the call delegates to the core::str::FromStr
implementation on I128<SCALE>.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::Num;
let v = I128s12::from_str_radix("1", 10).expect("parse 1");
assert_eq!(v, I128s12::ONE);
assert!(I128s12::from_str_radix("1", 16).is_err());type FromStrRadixErr = ParseDecimalError
Source§impl<const SCALE: u32> NumCast for I128<SCALE>
impl<const SCALE: u32> NumCast for I128<SCALE>
Source§fn from<T: ToPrimitive>(n: T) -> Option<Self>
fn from<T: ToPrimitive>(n: T) -> Option<Self>
Casts any T: ToPrimitive value to I128<SCALE>.
Uses the f64 conversion path for inputs that carry fractional
information, and the i128 path for integer-shaped inputs. The
integer path is taken when (to_i128() as f64) == to_f64(), which
holds for true integer types even when their magnitude exceeds f64’s
exact-integer range of 2^53. Returns None when neither path
produces a representable value.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
use num_traits::NumCast;
let from_int: I128s12 = NumCast::from(42_i32).unwrap();
assert_eq!(from_int, I128s12::from_bits(42_000_000_000_000));
let from_float: I128s12 = NumCast::from(1.5_f64).unwrap();
assert_eq!(from_float, I128s12::from_f64_lossy(1.5));
let nan: Option<I128s12> = NumCast::from(f64::NAN);
assert!(nan.is_none());Source§impl<const SCALE: u32> Octal for I128<SCALE>
impl<const SCALE: u32> Octal for I128<SCALE>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats the raw i128 storage in octal.
See fmt::LowerHex for the storage-versus-value distinction.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(format!("{:o}", I128s12::ZERO), "0");Source§impl<const SCALE: u32> One for I128<SCALE>
impl<const SCALE: u32> One for I128<SCALE>
Source§fn is_one(&self) -> bool
fn is_one(&self) -> bool
Returns true if self equals the multiplicative identity.
Provided explicitly rather than relying on the default so that the check is a single integer comparison instead of going through the multiplication chain.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::One;
assert!(I128s12::ONE.is_one());
assert!(!I128s12::ZERO.is_one());Source§impl<const SCALE: u32> Ord for I128<SCALE>
impl<const SCALE: u32> Ord for I128<SCALE>
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl<const SCALE: u32> PartialEq for I128<SCALE>
impl<const SCALE: u32> PartialEq for I128<SCALE>
Source§impl<const SCALE: u32> PartialOrd for I128<SCALE>
impl<const SCALE: u32> PartialOrd for I128<SCALE>
Source§impl<const SCALE: u32> Rem for I128<SCALE>
impl<const SCALE: u32> Rem for I128<SCALE>
Source§fn rem(self, rhs: Self) -> Self
fn rem(self, rhs: Self) -> Self
Compute the remainder of dividing self by rhs, truncated toward
zero.
Because both operands share the same SCALE, the raw remainder
self.0 % rhs.0 already lives in value * 10^S form without any
rescaling. Behavior matches i128 %: the result has the same sign
as the dividend.
§Panics
Panics on rhs == ZERO (division by zero), matching i128 %.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(5_500_000_000_000); // 5.5
let b = I128s12::from_bits(2_000_000_000_000); // 2.0
assert_eq!((a % b).to_bits(), 1_500_000_000_000); // 1.5Source§impl<const SCALE: u32> RemAssign for I128<SCALE>
impl<const SCALE: u32> RemAssign for I128<SCALE>
Source§fn rem_assign(&mut self, rhs: Self)
fn rem_assign(&mut self, rhs: Self)
Compute the remainder of self / rhs and store it in self.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> Shl<u32> for I128<SCALE>
impl<const SCALE: u32> Shl<u32> for I128<SCALE>
Source§fn shl(self, n: u32) -> Self
fn shl(self, n: u32) -> Self
Left-shift the underlying i128 storage by n bits.
Operates on raw bits, not the logical decimal value.
Delegates to i128 << n.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Panics
Panics in debug builds when n >= 128; wraps modulo 128 in
release builds (standard Rust integer-shift contract).
§Examples
use decimal_scaled::I128s12;
assert_eq!(I128s12::from_bits(1) << 3u32, I128s12::from_bits(8));Source§impl<const SCALE: u32> ShlAssign<u32> for I128<SCALE>
impl<const SCALE: u32> ShlAssign<u32> for I128<SCALE>
Source§fn shl_assign(&mut self, n: u32)
fn shl_assign(&mut self, n: u32)
In-place left-shift of the underlying i128 storage by n bits.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> Shr<u32> for I128<SCALE>
impl<const SCALE: u32> Shr<u32> for I128<SCALE>
Source§fn shr(self, n: u32) -> Self
fn shr(self, n: u32) -> Self
Arithmetic (sign-extending) right-shift of the underlying i128
storage by n bits.
Negative values remain negative: the vacated high bits are filled
with the sign bit (ones for negative, zero for non-negative).
Use I128::unsigned_shr for a logical (zero-fill) right shift.
Operates on raw bits, not the logical decimal value.
Delegates to i128 >> n.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Panics
Panics in debug builds when n >= 128; wraps modulo 128 in
release builds.
§Examples
use decimal_scaled::I128s12;
// Arithmetic shift: -8 >> 1 == -4.
assert_eq!(I128s12::from_bits(-8) >> 1u32, I128s12::from_bits(-4));Source§impl<const SCALE: u32> ShrAssign<u32> for I128<SCALE>
impl<const SCALE: u32> ShrAssign<u32> for I128<SCALE>
Source§fn shr_assign(&mut self, n: u32)
fn shr_assign(&mut self, n: u32)
In-place arithmetic (sign-extending) right-shift of the underlying
i128 storage by n bits.
Operates on raw bits, not the logical decimal value.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> Signed for I128<SCALE>
impl<const SCALE: u32> Signed for I128<SCALE>
Source§fn abs(&self) -> Self
fn abs(&self) -> Self
Returns the absolute value of self.
Delegates to the inherent I128::abs method.
§Panics
Panics in debug mode when called on I128::MIN because the
positive counterpart of i128::MIN is not representable. In
release mode the result wraps.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::Signed;
let pos = I128s12::from_bits(1_500_000_000_000);
let neg = I128s12::from_bits(-1_500_000_000_000);
assert_eq!(neg.abs(), pos);Source§fn signum(&self) -> Self
fn signum(&self) -> Self
Returns the sign of self as a scaled I128: -ONE, ZERO, or +ONE.
Delegates to the inherent I128::signum method.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::Signed;
assert_eq!(I128s12::from_bits(5).signum(), I128s12::ONE);
assert_eq!(I128s12::from_bits(-5).signum(), -I128s12::ONE);
assert_eq!(I128s12::ZERO.signum(), I128s12::ZERO);Source§fn is_positive(&self) -> bool
fn is_positive(&self) -> bool
Returns true if self is strictly greater than zero.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::Signed;
assert!(I128s12::ONE.is_positive());
assert!(!I128s12::ZERO.is_positive());
assert!(!(-I128s12::ONE).is_positive());Source§fn is_negative(&self) -> bool
fn is_negative(&self) -> bool
Returns true if self is strictly less than zero.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::Signed;
assert!((-I128s12::ONE).is_negative());
assert!(!I128s12::ZERO.is_negative());
assert!(!I128s12::ONE.is_negative());Source§fn abs_sub(&self, other: &Self) -> Self
fn abs_sub(&self, other: &Self) -> Self
Returns self - other when self > other, otherwise ZERO.
Matches the num_traits::Signed::abs_sub contract: the result is
never negative. This is not the same as (self - other).abs().
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::Signed;
let two = I128s12::from_bits(2_000_000_000_000);
let five = I128s12::from_bits(5_000_000_000_000);
let three = I128s12::from_bits(3_000_000_000_000);
assert_eq!(five.abs_sub(&two), three);
assert_eq!(two.abs_sub(&five), I128s12::ZERO);
assert_eq!(five.abs_sub(&five), I128s12::ZERO);Source§impl<const SCALE: u32> Sub for I128<SCALE>
impl<const SCALE: u32> Sub for I128<SCALE>
Source§fn sub(self, rhs: Self) -> Self
fn sub(self, rhs: Self) -> Self
Subtract rhs from self.
No rescaling needed; raw storage values are subtracted directly.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let a = I128s12::from_bits(3_000_000_000_000); // 3.0
let b = I128s12::from_bits(1_500_000_000_000); // 1.5
assert_eq!((a - b).to_bits(), 1_500_000_000_000);Source§impl<const SCALE: u32> SubAssign for I128<SCALE>
impl<const SCALE: u32> SubAssign for I128<SCALE>
Source§fn sub_assign(&mut self, rhs: Self)
fn sub_assign(&mut self, rhs: Self)
Subtract rhs from self in place.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
Source§impl<const SCALE: u32> ToPrimitive for I128<SCALE>
impl<const SCALE: u32> ToPrimitive for I128<SCALE>
Source§fn to_i64(&self) -> Option<i64>
fn to_i64(&self) -> Option<i64>
Converts self to i64 by truncating the fractional part toward zero.
Returns None when the integer part of self falls outside
i64’s range. Unlike to_int_lossy, which saturates, this method
is contractually fallible.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::ToPrimitive;
let v = I128s12::from_bits(2_500_000_000_000); // 2.5
assert_eq!(v.to_i64(), Some(2));
assert_eq!(I128s12::MAX.to_i64(), None);Source§fn to_u64(&self) -> Option<u64>
fn to_u64(&self) -> Option<u64>
Converts self to u64 by truncating the fractional part toward zero.
Returns None for negative values and for values whose integer part
exceeds u64::MAX.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::ToPrimitive;
let v = I128s12::from_bits(42_000_000_000_000);
assert_eq!(v.to_u64(), Some(42));
assert_eq!((-I128s12::ONE).to_u64(), None);Source§fn to_i128(&self) -> Option<i128>
fn to_i128(&self) -> Option<i128>
Converts self to i128 by truncating the fractional part toward zero.
Always returns Some because self.0 / 10^SCALE fits in i128
by construction.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::ToPrimitive;
let v = I128s12::from_bits(42_000_000_000_000);
assert_eq!(v.to_i128(), Some(42));
assert!(I128s12::MAX.to_i128().is_some());Source§fn to_u128(&self) -> Option<u128>
fn to_u128(&self) -> Option<u128>
Converts self to u128 by truncating the fractional part toward zero.
Returns None for negative values.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::ToPrimitive;
assert_eq!(I128s12::ZERO.to_u128(), Some(0));
assert_eq!(I128s12::from_bits(-1).to_u128(), None);Source§fn to_f32(&self) -> Option<f32>
fn to_f32(&self) -> Option<f32>
Converts self to f32.
Uses the I128::to_f32_lossy helper. Always returns Some; the
result may be +/-inf for very large magnitudes.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
use num_traits::ToPrimitive;
let v = I128s12::from_bits(1_500_000_000_000); // 1.5
assert_eq!(v.to_f32(), Some(1.5_f32));Source§fn to_f64(&self) -> Option<f64>
fn to_f64(&self) -> Option<f64>
Converts self to f64.
Uses the I128::to_f64_lossy helper. Always returns Some; the
result may be +/-inf for very large magnitudes.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::I128s12;
use num_traits::ToPrimitive;
let v = I128s12::from_bits(1_500_000_000_000); // 1.5
assert_eq!(v.to_f64(), Some(1.5_f64));Source§fn to_isize(&self) -> Option<isize>
fn to_isize(&self) -> Option<isize>
self to an isize. If the value cannot be
represented by an isize, then None is returned.Source§fn to_i8(&self) -> Option<i8>
fn to_i8(&self) -> Option<i8>
self to an i8. If the value cannot be
represented by an i8, then None is returned.Source§fn to_i16(&self) -> Option<i16>
fn to_i16(&self) -> Option<i16>
self to an i16. If the value cannot be
represented by an i16, then None is returned.Source§fn to_i32(&self) -> Option<i32>
fn to_i32(&self) -> Option<i32>
self to an i32. If the value cannot be
represented by an i32, then None is returned.Source§fn to_usize(&self) -> Option<usize>
fn to_usize(&self) -> Option<usize>
self to a usize. If the value cannot be
represented by a usize, then None is returned.Source§fn to_u8(&self) -> Option<u8>
fn to_u8(&self) -> Option<u8>
self to a u8. If the value cannot be
represented by a u8, then None is returned.Source§impl<const SCALE: u32> TryFrom<f32> for I128<SCALE>
impl<const SCALE: u32> TryFrom<f32> for I128<SCALE>
Source§fn try_from(value: f32) -> Result<Self, Self::Error>
fn try_from(value: f32) -> Result<Self, Self::Error>
Widens value to f64 and delegates to TryFrom<f64>.
Returns Err(NotFinite) for NaN and the infinities; Err(Overflow)
for finite values whose magnitude exceeds I128::MAX after scaling.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::{I128s12, DecimalConvertError};
let v: I128s12 = 1.0_f32.try_into().unwrap();
assert_eq!(v, I128s12::ONE);
let nan: Result<I128s12, _> = f32::NAN.try_into();
assert_eq!(nan, Err(DecimalConvertError::NotFinite));Source§type Error = DecimalConvertError
type Error = DecimalConvertError
Source§impl<const SCALE: u32> TryFrom<f64> for I128<SCALE>
impl<const SCALE: u32> TryFrom<f64> for I128<SCALE>
Source§fn try_from(value: f64) -> Result<Self, Self::Error>
fn try_from(value: f64) -> Result<Self, Self::Error>
Multiplies value by 10^SCALE in f64 and truncates to i128.
Returns Err(NotFinite) for NaN/inf, and Err(Overflow) for
finite inputs whose scaled value falls outside [i128::MIN, i128::MAX).
Note: i128::MAX as f64 rounds up to 2^127 because i128::MAX
(2^127 - 1) is not exactly representable in f64. The range check
uses a strict < on the upper bound to reject 2^127 itself.
§Precision
Lossy: involves f32 or f64 at some point; result may lose precision.
§Examples
use decimal_scaled::{I128s12, DecimalConvertError};
let v: I128s12 = 1.0_f64.try_into().unwrap();
assert_eq!(v, I128s12::ONE);
let nan: Result<I128s12, _> = f64::NAN.try_into();
assert_eq!(nan, Err(DecimalConvertError::NotFinite));
let overflow: Result<I128s12, _> = 1e30_f64.try_into();
assert_eq!(overflow, Err(DecimalConvertError::Overflow));Source§type Error = DecimalConvertError
type Error = DecimalConvertError
Source§impl<const SCALE: u32> TryFrom<i128> for I128<SCALE>
impl<const SCALE: u32> TryFrom<i128> for I128<SCALE>
Source§fn try_from(value: i128) -> Result<Self, Self::Error>
fn try_from(value: i128) -> Result<Self, Self::Error>
Scales value by 10^SCALE using checked multiplication.
Returns Err(Overflow) if the product exceeds i128::MAX or
falls below i128::MIN.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::{I128s12, DecimalConvertError};
let v: I128s12 = 1_i128.try_into().unwrap();
assert_eq!(v, I128s12::ONE);
let overflow: Result<I128s12, _> = i128::MAX.try_into();
assert_eq!(overflow, Err(DecimalConvertError::Overflow));Source§type Error = DecimalConvertError
type Error = DecimalConvertError
Source§impl<const SCALE: u32> TryFrom<u128> for I128<SCALE>
impl<const SCALE: u32> TryFrom<u128> for I128<SCALE>
Source§fn try_from(value: u128) -> Result<Self, Self::Error>
fn try_from(value: u128) -> Result<Self, Self::Error>
Converts value to i128, then scales by 10^SCALE.
Returns Err(Overflow) if value > i128::MAX or if the scaled
product overflows i128.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::{I128s12, DecimalConvertError};
let v: I128s12 = 42_u128.try_into().unwrap();
assert_eq!(v.to_bits(), 42_000_000_000_000);
let overflow: Result<I128s12, _> = u128::MAX.try_into();
assert_eq!(overflow, Err(DecimalConvertError::Overflow));Source§type Error = DecimalConvertError
type Error = DecimalConvertError
Source§impl<const SCALE: u32> UpperExp for I128<SCALE>
impl<const SCALE: u32> UpperExp for I128<SCALE>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats the value in scientific notation with an uppercase E.
Identical to fmt::LowerExp except the exponent separator is E.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
let v = I128s12::from_bits(1_500_000_000_000);
assert_eq!(format!("{v:E}"), "1.5E0");Source§impl<const SCALE: u32> UpperHex for I128<SCALE>
impl<const SCALE: u32> UpperHex for I128<SCALE>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats the raw i128 storage as uppercase hex.
See fmt::LowerHex for the storage-versus-value distinction.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
assert_eq!(format!("{:X}", I128s12::ONE), "E8D4A51000");Source§impl<const SCALE: u32> Zero for I128<SCALE>
impl<const SCALE: u32> Zero for I128<SCALE>
Source§fn zero() -> Self
fn zero() -> Self
Returns the additive identity for I128<SCALE>.
Equivalent to I128::ZERO.
§Precision
Strict: all arithmetic is integer-only; result is bit-exact.
§Examples
use decimal_scaled::I128s12;
use num_traits::Zero;
assert_eq!(I128s12::zero(), I128s12::ZERO);