zeekayandHanzo Dev e7ede18d50 fix: Parse enforces the decimal grammar itself, so "--5" is not +5
Parse stripped one leading sign and let big.Int.SetString read what was
left. SetString accepts a sign too, so a second one was consumed there:
"--5" parsed as POSITIVE five. On the values this package exists to hold
that is a credit read as a charge, and it is silent — the caller gets a
well-formed Decimal with no error to notice.

The same gap had a second side. A bare "-", "+" or "." reached the
intPart=="" → "0" fallback with no digits at all and parsed as a
confident zero, indistinguishable from a real "0".

Both come from delegating the grammar check to big.Int, which answers a
different question than "is this a decimal literal". Checking the digits
here answers that one, and it is the only check the grammar needs.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 22:05:17 -07:00

decimal

Exact, arbitrary-precision fixed-point decimal for Go. A value is coefficient × 10⁻ˢᶜᵃˡᵉ with a big.Int coefficient — no precision ceiling, no float, immutable.

Unlike int64/uint64 decimal & money libraries (which cap around 19 digits — about $9.20 at 18 decimals), this holds a fiat cent and an 18-decimal on-chain wei balance with equal exactness. 0.1 + 0.2 is exactly 0.3.

d := decimal.MustParse("6.60")
cost := decimal.New(200, 0).Mul(d).Quo(decimal.New(1_000_000, 0), 18) // 200 tokens @ $6.60/1M
cost.String() // "0.00132"  (never floored to 0)

The numeric core beneath hanzoai/money. Stdlib only. BSD-3-Clause.

S
Description
Exact big.Int fixed-point decimal for Go — no precision ceiling, no float
Readme
51 KiB
Languages
Go 100%