Skip to content

Latest commit

 

History

49 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

decimal-go logo An arbitrary-precision decimal arithmetic library for Go.

Go License decimal.js Dependencies

Tests Race detector Cross-validated Performance Playground

A Go implementation inspired by the behavior and API of decimal.js.


About

decimal-go is a Go implementation inspired by the behavior and API of decimal.js, created during the Port Mortem 2026 hackathon.

Goals

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

Installation

decimal-go has zero external dependencies and requires Go 1.25+.

go get github.com/iSundram/decimal-go

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

Quick Start

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.

Status

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.

Validation added in this fork

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 decimal-go (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, with Plus, Minus, Times, ValueOf as the primary Go names), plus ToJSON/MarshalJSON — all equal-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 the Constructor (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 upstream log(0, base) parity behavior (see docs/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.

Contributing

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.

Acknowledgements

MikeMcl
Michael Mclaughlin
Huge thanks to Michael Mclaughlin for the original decimal.js library, which heavily inspired the API, design, and behavior of this project.

Contributors

Thanks goes to these wonderful people who have contributed to this project. This section automatically updates as new developers join in!

Contributors

License

This project is released under the MIT License.


Made with Go.

About

An arbitrary-precision decimal arithmetic library for Go.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages