var ErrZeroDenominator
ErrZeroDenominator is returned when a denominator of zero is requested.
Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.
Package fraction is exact rational arithmetic as a pure, reusable package: values are p/q with int64 numerator and de...
gno.land/p/moul/x/daily/fraction/v0Exact rational arithmetic — New, Int, Zero, Add, Sub, Mul,
Div, Neg, Cmp, Equal, String, Decimal.
Values are p/q with int64 numerator and denominator, always in lowest terms
with a positive denominator.
1import "gno.land/p/moul/x/daily/fraction/v0"
2
3third, _ := fraction.New(1, 3)
4sum, ok := third.Add(third) // 2/3, ok
5sum, ok = sum.Add(third) // exactly 1 — not 0.9999…
6fraction.Decimal(third, 5) // "0.33333"
This exists because there are no floats worth trusting on chain. 0.1 + 0.2
is not 0.3 in binary floating point, and a consensus system cannot afford an
answer that depends on rounding. A fraction is exact; it only becomes lossy at
the moment you ask for a decimal, and Decimal makes that moment explicit —
the caller chooses how much to lose and when.
Overflow is reported, never wrapped. Every operation returns ok=false on
int64 overflow rather than silently producing a wrapped numerator, which would
be a wrong answer that looks perfectly fine.
Cmp cross-multiplies, so comparison is exact too: 1/3 and 33333/100000 are
identical to five decimal places, and it still knows which is larger.
The sign always lives in the numerator, so 1/-2 and -1/2 are the same value.
The zero value of the type behaves as 0/1 rather than dividing by zero.
Live demo: r/moul/x/daily/fractiondemo
· render it at /r/moul/x/daily/fractiondemo/v0.
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.
Package fraction is exact rational arithmetic as a pure, reusable package: values are p/q with int64 numerator and denominator, always kept in lowest terms with a positive denominator.
This exists because there are no floats worth trusting on chain. 0.1 + 0.2 is not 0.3 in binary floating point, and a consensus system cannot afford an answer that depends on rounding. A fraction is exact: one third really is one third, and only becomes lossy at the moment you ask for a decimal.
Every operation is checked for int64 overflow and returns ok=false rather than silently wrapping — a wrapped numerator would be a wrong answer that looks fine.
A live demo of this package is at r/moul/x/daily/fractiondemo(/r/moul/x/daily/fractiondemo/v0).
ErrZeroDenominator is returned when a denominator of zero is requested.
Decimal renders f with exactly places digits after the point, truncated toward zero. THIS is where exactness ends — 1/3 cannot be written in decimal, so the caller chooses how much to lose and when.
Int returns n as n/1.
New returns num/den reduced, or an error when den is zero.
Zero is 0/1.
Fraction is an exact rational number in lowest terms, denominator > 0.
Add returns f+g. ok is false on int64 overflow.
Cmp returns -1, 0 or +1 as f is less than, equal to, or greater than g. Compares by cross-multiplication, so it is exact — no decimal conversion.
Den returns the denominator, which is always > 0. The zero value of the type has den == 0, so treat it as 1 to keep an un-initialised Fraction usable.
Div returns f/g. ok is false on overflow or division by zero.
Equal reports exact equality.
IsZero reports whether f == 0.
Mul returns f*g. ok is false on int64 overflow.
Neg returns -f.
Num returns the numerator; Den the (always positive) denominator.
String renders "p/q", or just "p" when the denominator is 1.
Sub returns f-g. ok is false on int64 overflow.