Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package fraction is exact rational arithmetic as a pure, reusable package: values are p/q with int64 numerator and de...

Readme View source

gno.land/p/moul/x/daily/fraction/v0

Exact rational arithmeticNew, 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.

Overview

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).

Variables 1

var ErrZeroDenominator

1var ErrZeroDenominator = errors.New("fraction: zero denominator")
source

ErrZeroDenominator is returned when a denominator of zero is requested.

Functions 4

func Decimal

1func Decimal(f Fraction, places int) string
source

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.

func Int

1func Int(n int64) Fraction
source

Int returns n as n/1.

func New

1func New(num, den int64) (Fraction, error)
source

New returns num/den reduced, or an error when den is zero.

func Zero

1func Zero() Fraction
source

Zero is 0/1.

Types 1

type Fraction

struct
1type Fraction struct {
2	num, den int64
3}
source

Fraction is an exact rational number in lowest terms, denominator > 0.

Methods on Fraction

func Add

method on Fraction
1func (f Fraction) Add(g Fraction) (Fraction, bool)
source

Add returns f+g. ok is false on int64 overflow.

func Cmp

method on Fraction
1func (f Fraction) Cmp(g Fraction) int
source

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.

func Den

method on Fraction
1func (f Fraction) Den() int64
source

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.

func Div

method on Fraction
1func (f Fraction) Div(g Fraction) (Fraction, bool)
source

Div returns f/g. ok is false on overflow or division by zero.

func Equal

method on Fraction
1func (f Fraction) Equal(g Fraction) bool
source

Equal reports exact equality.

func IsZero

method on Fraction
1func (f Fraction) IsZero() bool
source

IsZero reports whether f == 0.

func Mul

method on Fraction
1func (f Fraction) Mul(g Fraction) (Fraction, bool)
source

Mul returns f*g. ok is false on int64 overflow.

func Neg

method on Fraction
1func (f Fraction) Neg() Fraction
source

Neg returns -f.

func Num

method on Fraction
1func (f Fraction) Num() int64
source

Num returns the numerator; Den the (always positive) denominator.

func String

method on Fraction
1func (f Fraction) String() string
source

String renders "p/q", or just "p" when the denominator is 1.

func Sub

method on Fraction
1func (f Fraction) Sub(g Fraction) (Fraction, bool)
source

Sub returns f-g. ok is false on int64 overflow.

Imports 3

  • errors stdlib
  • strconv stdlib
  • strings stdlib

Source Files 3