is a Go implementation inspired by the behavior and API of
decimal.js, created during the Port Mortem 2026 hackathon.
- Preserve the behavior of the original library as closely as possible.
- Provide an idiomatic Go API.
- Maintain high test compatibility.
- Produce clean, well-documented Go code.
has zero external dependencies and requires Go 1.25+.
go get github.com/iSundram/decimal-goThen import it in your code:
import "github.com/iSundram/decimal-go"Values are arbitrary-precision and immutable; every operation returns a new
value. The package-level New uses the default constructor (precision 20,
half-up rounding).
package main
import (
"fmt"
"github.com/iSundram/decimal-go"
)
func main() {
// Money math without the float rounding surprises of float64.
price := decimal.New("19.99")
qty := decimal.New("3")
total := price.Times(qty)
fmt.Println(total) // 59.97
// Exact value parsing from strings, integers, floats or *big.Int.
fmt.Println(decimal.New("0.1").Plus(decimal.New("0.2"))) // 0.3
// Custom precision via a cloned constructor.
c := decimal.Default.Clone(&decimal.Config{Precision: decimal.I64(50)})
pi := c.New("3.14159265358979323846264338327950288419716939937510")
fmt.Println(pi.ToFixed(30))
}Output:
59.97
0.3
3.141592653589793238462643383280
See the documentation site, the interactive playground (the real library compiled to WebAssembly, running in your browser), the example tests, the operations matrix, the decimal.js migration guide, the design decisions and the changelog for more.
Test suite fully ported.
The complete decimal.js test suite (61 modules) is ported to Go: every
module is covered by white-box tests in package decimal, and
go test ./... is green.
- Run the suite:
go test -count=1 ./... - Run with the race detector:
go test -race -count=1 . - Porting rules live in
PORTING_TESTS.md.
Beyond the ported suites, exact parity with the live decimal.js is proven by
additional committed tests and tooling:
- Cross-validation (
xvalidate/): a shared corpus of values is run through both(
go run) and the real decimal.js (node); the two outputs are byte-for-byte identical (bash xvalidate/compare.sh, 1518/1518 lines). - API parity (
parity.go): every decimal.js long-form method name is available (39 as alias methods here, withPlus,Minus,Times,ValueOfas the primary Go names), plusToJSON/MarshalJSON— allequal-checked against the primary methods. - Property-based tests (
property_test.go): round-trip, commutativity, add/sub & mul/div inverses, sqrt/cbrt/exp-log inverses, comparisons, exact sqrt, modulo range. - Stress + race tests (
stress_test.go): precision 400–2048, integer boundaries, NaN/Infinity, and 64 concurrent clone-constructors under-race. A genuine data race inherited from decimal.js's module globals (external/inexact/quadrant) was found and fixed by moving those flags onto theConstructor(matching decimal.js's "one clone per context" model). - Regression tests (
regression_test.go): the three bugs fixed while porting (pow10 overflow, Pow negative-base index,1^±Inf), plus the inherited upstreamlog(0, base)parity behavior (seedocs/DECISIONS.md§11–12), are locked in. - Input matrix (
input_test.go): every decimal.js value type (number, string,big.Int,Decimal,-0, NaN, ±Infinity) accepted. - Operations matrix (
MATRIX.md) documents every op, its rounding semantics and edge cases. - Benchmarks (
bench/README.md+results.txt): honest Go-vs-JS comparison (23 of 25 directly comparable pairs are faster in Go, up to ~3× on multiplication and division);New(string)parsing is ~1.45× slower and parse+op+format round trips ~1.7× slower, because real-world benchmarks that re-parse inputs pay Go's allocation overhead while JS string parsing is heavily JIT-optimised.
We welcome contributions! Please see our Contributing Guide for details on how to get started. Security issues and the vulnerability-reporting policy are covered in SECURITY.md.
|
Michael Mclaughlin |
Huge thanks to Michael Mclaughlin for the original decimal.js library, which heavily inspired the API, design, and behavior of this project.
|
Thanks goes to these wonderful people who have contributed to this project. This section automatically updates as new developers join in!
This project is released under the MIT License.