Rational
An exact rational number — a numerator/denominator pair over Long, kept reduced to lowest terms with a strictly positive denominator.
The scheduler's virtual times are rationals (b + committedService / weight, design §7.1) and the whole point of the policy is that every replica orders children bit-identically on JVM, Native, and wasmJs. Floating point does not give that — 0.1 + 0.2 is not 0.3 and rounds differently across platforms — so the policy never converts a virtual time to Double/Float. All arithmetic here is exact integer math, reduced after every operation to keep magnitudes small, and overflow-checked: an add or multiply that would exceed Long.MAX_VALUE throws ArithmeticException rather than wrapping to a wrong order (the same discipline as Weight and CheckedMath).
BigInteger would sidestep overflow entirely but is a JVM-only type — unavailable in this module's commonMain — so the exact-but-bounded Long rational is the portable choice; the reduce-after-every-op keeps realistic scheduler workloads far from the ceiling.
Deliberately not @Serializable. The generated serializer would deserialize past of — the only path that reduces and forces a positive denominator — so an unreduced or sign-denormalized value could arrive over the wire and break equals/compareTo exactly as it could for Weight (#1647). Leaving the annotation off makes that unreachable by default: a type that wants to replicate a Rational cannot simply inherit wire-legality, it has to name a normalizing serializer at the property.
Replication is opt-in, per site, through RationalSerializer — the normalizing serializer routed through of that this stance always prescribed, and the same shape as WeightSerializer. Two sites exist today: PolicyEdge.virtualOffset is scheduler-local and design §7.2 explicitly does not replicate it, while Gauge.floor is replicated (issue #1752) and carries @Serializable(with = RationalSerializer::class). Annotate the property, never this class — that is what keeps the default closed.
Properties
Functions
Order by exact cross-multiplication: a/b <=> c/d compares a*d against c*b. Both denominators are positive, so no sign flip is needed. Products are overflow-checked, so an out-of-range comparison throws rather than wrapping to a wrong verdict.
The exact difference, reduced. Throws ArithmeticException on Long overflow.
The exact sum, reduced. Throws ArithmeticException on Long overflow.
The exact product, reduced. Throws ArithmeticException on Long overflow.