go-ruby-rational

Ruby's Rational exact number type in pure Go โ€” MRI byte-exact, no cgo.

pure Go ยท zero cgo Rational-compatible exact arithmetic arbitrary precision lowest terms to_s vs inspect half-away-from-zero digit-aware rounding MRI byte-exact 100% coverage 6 arches
Documentation GitHub
Documentation (MkDocs Material + mike) License: BSD-3-Clause Go 1.26.4+ Coverage 100%

go-ruby-rational is a pure-Go (no cgo) reimplementation of Ruby's Rational โ€” the exact numerator/denominator number type backing literals like 3r and the Rational() method โ€” byte-exact against MRI. A Rational holds an arbitrary-precision ratio in lowest terms with a positive denominator (the sign on the numerator), and every arithmetic, comparison and conversion method reproduces MRI's result exactly: inspect prints (3/4) while to_s prints 3/4; rounding is half-away-from-zero; the digit-aware floor/ceil/round return a Rational for n ≥ 1 but an Integer for n ≤ 0. It is the Rational backend for go-embedded-ruby, bound by rbgo as a native module like go-ruby-bigdecimal โ€” differential-tested against MRI, 100% coverage, CI green across 6 arches and 3 OSes.

Exact arithmetic ready

Add / Sub / Mul / Div over arbitrary-precision integers (a math/big.Rat core), always reduced to lowest terms with a positive denominator; Div by zero raises ErrZeroDivision (MRI ZeroDivisionError), as do Reciprocal of zero and 0r ** -1.

Pow โ€” exact, with Float fallback ready

Pow keeps an integer exponent exact ((3/4) ** -1 == (4/3)); PowFloat provides MRI’s Float fallback (a.to_f ** exp) for a Rational/Float exponent.

Normalisation ready

Rational(2, 4) โ†’ (1/2), negative-denominator folding (Rational(1, -2) โ†’ (-1/2)), Rational(0, n) โ†’ (0/1) โ€” Ruby’s normalisation with the sign on the numerator.

ToS vs Inspect & conversions ready

MRI’s split โ€” to_s โ†’ "3/4", inspect โ†’ "(3/4)" (String() returns the inspect form). ToI (truncate toward zero), ToF (nearest-even), ToR, and Truncate/Floor/Ceil/Round to an Integer.

Digit-aware rounding ready

FloorN / CeilN / RoundN / TruncateN return a Rational for n >= 1 and an Integer for n <= 0, with MRI’s half-away-from-zero rounding ((5/2).round == 3, (-5/2).round == -3).

Comparison, Parse & differential oracle ready

Cmp/Eql/EqlStrict against Rational, Integer and Float (NaN undefined like MRI’s nil); Parse for Rational(String). A wide corpus is inspected here and by the system ruby, compared byte-for-byte; 100% coverage, gofmt + go vet clean, green across all six 64-bit Go arches and three OSes.

A faithful port of Ruby's Rational in pure Go, cgo disabled, so it cross-compiles and embeds anywhere. An arbitrary-precision math/big.Rat core always reduced to lowest terms with a positive denominator, exact + - * / and integer **, the to_s/inspect split, half-away-from-zero rounding and the digit-aware Rational/Integer return rule. Validated differentially against the system ruby binary. It is a standalone, reusable module bound into the sibling org github.com/go-embedded-ruby, and is distinct from go-composites/rational, which models a generic mathematical rational rather than Ruby's exact semantics.