gitmyhub

decimal

Go ★ 7.4k updated 3mo ago

Arbitrary-precision fixed-point decimal numbers in Go

A Go library for precise decimal arithmetic that eliminates the rounding errors ordinary floating-point numbers produce, making it safe to handle money, prices, and financial totals in Go applications.

Gosetup: easycomplexity 2/5

This is a Go library for working with decimal numbers at arbitrary precision. It exists to solve a problem that trips up many programs handling money: ordinary floating-point numbers in computers cannot represent values like 0.1 exactly. When you do repeated arithmetic with those numbers, small rounding errors accumulate and, in a financial context, that means cents or fractions of cents can appear or disappear from totals.

The library's decimal type supports addition, subtraction, and multiplication with no loss of precision. Division is supported with a precision level you specify. The README's FAQ walks through two concrete examples: a simple subtraction using standard Go float64 that produces 9.999999999999831 instead of 10, and a money-splitting scenario where the standard Go big.Rat type loses track of a fraction of a cent across three transactions.

The API is immutable: every method call returns a new decimal value and leaves the original unchanged. This design avoids a class of subtle bugs where a variable is accidentally modified through a shared reference. The README acknowledges the trade-off: immutability requires more memory allocations, so this library is slower than some alternatives. The assumption stated in the README is that code dealing with decimal numbers usually cares more about correctness than raw speed.

The library supports serialization to and from JSON, XML, and SQL databases without requiring any custom conversion code. It requires Go version 1.10 or later and is available via the standard go get command.

The README also links to four alternative libraries for situations where different trade-offs suit better: one optimized for arbitrary-precision performance similar to Go's big.Int, one with a compatible API but limited to 12 decimal digits, one with zero memory allocations at 19-digit precision, and one fork focused on billing and e-commerce cases with built-in BSON support.

Where it fits