128-bit fixed-point decimal numbers in go.
- High performance
- Minimal or zero memory allocation
- Precision up to 19 decimal places
- Fixed size memory layout (128 bits)
- No panic or error arithmetics (use NaN instead)
- Immutability (methods return new instances)
- Basic arithmetic operations required for financial calculations (specifically for banking and accounting)
- Additional arithmetic operations for scientific calculations
- Easy to use
- Easy to inegrate with external systems (e.g. databases, accounting systems, JSON, etc.)
- Financially correct rounding
- Correct comparison of numbers encoded in different precisions (e.g. 1.0 == 1.00)
- Correct handling of NaN values (e.g. NaN + 1 = NaN)
- Conversion to canonical representation (e.g. 1.0000 -> 1)
- Conversion to fixed string representation (e.g. 1.0000 -> "1.0000")
- Conversion to human-readable string representation (e.g. 1.0000 -> "1")
Run go get github.com/jokruger/dec128
This library requires Go version >=1.23
http://godoc.org/github.com/jokruger/dec128
package main
import (
"fmt"
"github.com/jokruger/dec128"
)
func main() {
principal := dec128.FromString("1000.00")
annualRate := dec128.FromString("5.0")
days := 30
dailyRate := annualRate.Div(dec128.FromInt(365))
dailyRate = dailyRate.Div(dec128.FromInt(100))
accruedInterest := principal.Mul(dailyRate).Mul(dec128.FromInt(days)).RoundBank(2)
fmt.Printf("Principal: %v\n", principal.StringFixed())
fmt.Printf("Annual Interest Rate: %v\n", annualRate.String())
fmt.Printf("Days: %v\n", days)
fmt.Printf("Accrued Interest: %v\n", accruedInterest.String())
total := principal.Add(accruedInterest).RoundBank(2)
fmt.Printf("Total after %v days: %v\n", days, total.StringFixed())
}
There are several other libraries that provide decimal arithmetic in Go. However, most of them are either too slow, too memory-intensive, or lack the integration features required for financial applications. This library aims to provide a high-performance, low-memory, and easy-to-use alternative to existing libraries.
The following benchmarks were run on a MacBook Pro (2019) with a 2.6 GHz 6-Core Intel Core i7 processor and 16 GB of RAM (https://github.com/jokruger/go-decimal-benchmark).
parse (ns/op) string (ns/op) add (ns/op) mul (ns/op) div (ns/op)
dec128.Dec128 13.986 36.404 10.518 7.637 34.129
udecimal.Decimal 22.383 44.740 11.998 11.141 40.701
alpacadecimal.Decimal 90.959 83.291 222.275 70.552 481.113
shopspring.Decimal 160.160 183.984 241.129 74.726 451.901
- Precision: The number of decimal places in a number. For example, 1.00 has a precision of 2 and 1.0000 has a precision of 4.
- Expontent: Same as precision, but in the context of low-level implementation details or Dec128 encoding.
- Canonical: The representation of a number with the minimum number of decimal places required to represent the number.
This project is licensed under the MIT License. See the LICENSE
file for details.
This project includes code derived from:
- A project licensed under the BSD 3-Clause License (Copyright © 2025 Quang).
- A project licensed under the MIT License (Copyright © 2019 Luke Champine).
See the LICENSE
file for full license texts.