summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-23 23:00:13 +0300
committerPaul Buetow <paul@buetow.org>2026-05-23 23:00:13 +0300
commitd5278c6d6984cc7dfdd1111d49f4fb385c71a15e (patch)
treed5b540cdc599c1d149a781d32f84f35d9879d800
parent79852fdaa2464c9e364f2f564f9b981814270926 (diff)
fix: preserve arbitrary precision in Rat.Compare() for Rat-to-Rat
Rat.Compare() converted all types to float64 first, then back to *big.Rat, defeating arbitrary precision. E.g., Rat(1/3) → float64(0.33333...) → imprecise *big.Rat. Now Rat-to-Rat uses direct n.Cmp() for exact comparison. Rat-to-Float still uses float64 → SetFloat64() (acceptable for non-Rat types).
-rw-r--r--internal/rpn/number.go7
1 files changed, 7 insertions, 0 deletions
diff --git a/internal/rpn/number.go b/internal/rpn/number.go
index f4134b1..562ef77 100644
--- a/internal/rpn/number.go
+++ b/internal/rpn/number.go
@@ -314,7 +314,14 @@ func (r *Rat) SetMetric(m *Metric) NumericValue {
}
// Compare returns -1, 0, or 1 if this rational is less than, equal to, or greater than another.
+// For Rat-to-Rat comparison, uses direct big.Rat.Cmp() for exact precision.
+// For Rat-to-Float comparison, converts via float64 (acceptable precision loss).
func (r *Rat) Compare(other NumericValue) (int, error) {
+ // Rat-to-Rat: direct comparison with full precision
+ if otherRat, ok := other.(*Rat); ok {
+ return r.n.Cmp(otherRat.n), nil
+ }
+ // Rat-to-Float or other: convert via float64 (acceptable precision loss)
otherF, err := other.Float64()
if err != nil {
return 0, fmt.Errorf("cannot compare: %w", err)