pub struct Ratio<T: RatioInteger> {
pub numer: T,
pub denom: T,
pub negative: bool,
}Expand description
A rational number represented as numerator/denominator with explicit sign.
§Type Parameter
T must implement RatioInteger, which includes all crypto-bigint types
from U64 through U16384.
§Invariants
- Denominator is never zero
- Values are not automatically reduced (call
normalizeexplicitly) - Sign is stored separately in the
negativefield - Zero is always represented with
negative = false
§Examples
use crypto_ratio::Ratio;
use crypto_bigint::U512;
let r = Ratio::<U512>::from_u64(2, 3);
assert_eq!(r.numer, U512::from_u64(2));
assert_eq!(r.denom, U512::from_u64(3));
assert!(!r.negative);Fields§
§numer: TThe numerator.
denom: TThe denominator.
negative: boolSign of the rational (true = negative).
Implementations§
Source§impl<T: RatioInteger> Ratio<T>
impl<T: RatioInteger> Ratio<T>
Sourcepub fn new_raw(numer: T, denom: T, negative: bool) -> Self
pub fn new_raw(numer: T, denom: T, negative: bool) -> Self
Create a ratio without reduction.
The denominator must be non-zero. This method is fast but the caller
is responsible for calling normalize if needed.
§Examples
use crypto_ratio::Ratio;
use crypto_bigint::U256;
let r = Ratio::new_raw(U256::from_u64(4), U256::from_u64(6), false);
assert_eq!(r.numer, U256::from_u64(4)); // Not reduced
assert_eq!(r.denom, U256::from_u64(6));Sourcepub fn new(numer: T, denom: T) -> Self
pub fn new(numer: T, denom: T) -> Self
Create a ratio with automatic GCD reduction.
This is slower than new_raw but ensures the result
is in lowest terms.
§Examples
use crypto_ratio::Ratio;
use crypto_bigint::U256;
let r = Ratio::new(U256::from_u64(4), U256::from_u64(6));
assert_eq!(r.numer, U256::from_u64(2)); // Reduced
assert_eq!(r.denom, U256::from_u64(3));Sourcepub fn from_u64(numer: u64, denom: u64) -> Self
pub fn from_u64(numer: u64, denom: u64) -> Self
Create from u64 with automatic reduction.
This is the most efficient constructor for small values.
§Examples
use crypto_ratio::RatioU256;
let r = RatioU256::from_u64(6, 8);
assert_eq!(r.to_f64_approx(), 0.75);Sourcepub fn is_positive(&self) -> bool
pub fn is_positive(&self) -> bool
Check if the ratio is positive.
Sourcepub fn is_negative(&self) -> bool
pub fn is_negative(&self) -> bool
Check if the ratio is negative.
Sourcepub fn is_integer(&self) -> bool
pub fn is_integer(&self) -> bool
Check if the ratio represents an integer (denominator is 1).
Sourcepub fn needs_reduction(&self) -> bool
pub fn needs_reduction(&self) -> bool
Check if the ratio should be reduced to prevent overflow.
Returns true if either numerator or denominator exceeds the reduction threshold (typically 70% of the type’s bit width).
Sourcepub fn normalize_if_needed(&mut self)
pub fn normalize_if_needed(&mut self)
Normalize only if needs_reduction returns true.
This is useful in loops to avoid unnecessary GCD operations.
Sourcepub fn normalize(&mut self)
pub fn normalize(&mut self)
Reduce the ratio to lowest terms using GCD.
This operation is optimized to:
- Return immediately if already reduced (GCD = 1)
- Use bit shifts for power-of-2 factors
- Normalize zero to 0/1
§Examples
use crypto_ratio::RatioU256;
let mut r = RatioU256::new_raw(
crypto_bigint::U256::from_u64(6),
crypto_bigint::U256::from_u64(8),
false
);
r.normalize();
assert_eq!(r.numer, crypto_bigint::U256::from_u64(3));
assert_eq!(r.denom, crypto_bigint::U256::from_u64(4));Sourcepub fn from_float(f: f64) -> Option<Self>
pub fn from_float(f: f64) -> Option<Self>
Convert an f64 to a ratio with automatic reduction.
Returns None if the input is infinite or NaN.
§Examples
use crypto_ratio::RatioU512;
let r = RatioU512::from_float(0.75).unwrap();
assert_eq!(r.numer, crypto_bigint::U512::from_u64(3));
assert_eq!(r.denom, crypto_bigint::U512::from_u64(4));Sourcepub fn to_f64_approx(&self) -> f64
pub fn to_f64_approx(&self) -> f64
Approximate conversion to f64.
Large values are scaled to fit in f64 range, potentially losing precision.
§Examples
use crypto_ratio::RatioU256;
let r = RatioU256::from_u64(1, 2);
assert!((r.to_f64_approx() - 0.5).abs() < 1e-10);Sourcepub fn mul(&self, other: &Self) -> Self
pub fn mul(&self, other: &Self) -> Self
Multiply two ratios without automatic reduction.
For reduced results, use mul_reduced or call
normalize afterward.
§Examples
use crypto_ratio::RatioU256;
let a = RatioU256::from_u64(2, 3);
let b = RatioU256::from_u64(3, 4);
let product = a.mul(&b);
// Result is 6/12 (unreduced)Sourcepub fn mul_reduced(&self, other: &Self) -> Self
pub fn mul_reduced(&self, other: &Self) -> Self
Multiply with smart reduction using fast heuristics.
This applies cheap reduction techniques:
- Power-of-2 factors via bit shifts (~10ns)
- Small value GCD using u64 (~50ns)
- Skips expensive full GCD for large coprime values
§Examples
use crypto_ratio::RatioU256;
let a = RatioU256::from_u64(2, 3);
let b = RatioU256::from_u64(3, 4);
let product = a.mul_reduced(&b);
// Result is 1/2 (reduced)Sourcepub fn div_by_uint(&self, divisor: &T) -> Self
pub fn div_by_uint(&self, divisor: &T) -> Self
Divide by an unsigned integer.
Multiplies the denominator by the divisor.
Sourcepub fn sub(&self, other: &Self) -> Self
pub fn sub(&self, other: &Self) -> Self
Subtract another ratio.
Equivalent to self.add(&other.neg()).