pub struct Ratio { /* private fields */ }Expand description
An exact non-negative rational over Ticks, always in lowest terms.
Non-negative because the value domain is unsigned (Rule Z, N12) and every
quantity this crate builds on rationals — durations, ratios of periods,
redshifts, density parameters — is non-negative. Differences that could go
negative are taken with Ratio::abs_diff, which makes the sign loss
explicit at the call site rather than silent in the type.
Arithmetic is exact. Where a result would leave the domain the operation fails
with UCAL-E0021; it never wraps and never approximates (Rules O, E). Operands
are pre-reduced by common factors before multiplying, which keeps intermediates
small enough that overflow is rare in practice without ever making it silent.
Implementations§
Source§impl Ratio
impl Ratio
Sourcepub fn new(num: Ticks, den: Ticks) -> Result<Ratio>
pub fn new(num: Ticks, den: Ticks) -> Result<Ratio>
Construct and reduce. UCAL-E0070 if the denominator is zero.
Sourcepub fn from_decimal_str(s: &str) -> Result<Ratio>
pub fn from_decimal_str(s: &str) -> Result<Ratio>
Parse an exact decimal such as "365.242190" or "1089.80".
§10.2 requires redshift inputs to parse exactly: 1100, 1089.80 and
0.5 are all exact rationals, and there is no float path in or out.
Rejects anything that is not digits with at most one decimal point.
Sourcepub fn is_integer(&self) -> bool
pub fn is_integer(&self) -> bool
Whether the value is a whole number.
Sourcepub fn sub(&self, other: &Ratio) -> Result<Ratio>
pub fn sub(&self, other: &Ratio) -> Result<Ratio>
self - other. UCAL-E0020 if the result would be negative — the type is
non-negative by construction, so this is Rule Z applied to rationals.
Sourcepub fn cmp_exact(&self, other: &Ratio) -> Ordering
pub fn cmp_exact(&self, other: &Ratio) -> Ordering
Exact comparison.
Cross-multiplies in the widened type, so comparison is total and can never
fail for overflow — which matters, because a comparison that could error
would make Ratio unusable as an interval endpoint.
Sourcepub fn snap(&self, digits: u32, mode: Rounding) -> Result<Ratio>
pub fn snap(&self, digits: u32, mode: Rounding) -> Result<Ratio>
The closest rational with denominator 10^digits, rounded in the stated
direction.
Exact rational accumulation is unbounded. Summing n terms whose
denominators are mutually coprime grows the common denominator like their
product, so a few dozen terms is enough to overflow any fixed-width
integer — long before a quadrature sum of thousands of panels finishes.
A certified sum therefore snaps each partial result back to a fixed
decimal grid, rounding outward: Rounding::Trunc for a value that
bounds from below, Rounding::Ceil for one that bounds from above. The
accumulator stays bounded and the enclosure stays rigorous, at the cost of
one grid step per snap — which is why callers choose a grid far finer than
the width they are trying to certify.
This is not a rendering: the result is still an exact Ratio, and Rule R
is untouched. It is a deliberate outward relaxation, and the only place
this crate discards information inside a computation rather than at its
edge.
Sourcepub fn to_decimal_string(&self, digits: u32, mode: Rounding) -> Result<String>
pub fn to_decimal_string(&self, digits: u32, mode: Rounding) -> Result<String>
Render to digits decimal places under an explicit mode (Rule R).
This is the only place a Ratio becomes inexact, and it is a rendering,
never a construction. UCAL-W0001 territory: the caller is told the mode
because it had to choose one.
Sourcepub fn to_ratio_string(&self) -> String
pub fn to_ratio_string(&self) -> String
Render as numerator/denominator, which is always exact.