High performance 128-bit fixed-point decimal numbers in go.
- High performance
- Zero dependencies
- Minimal or zero memory allocation
- Scale 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 integrate with external systems (e.g. databases, accounting systems, JSON, etc.)
- Financially correct rounding
- Correct comparison of numbers encoded in different scales (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.FromInt64(365))
dailyRate = dailyRate.Div(dec128.FromInt64(100))
accruedInterest := principal.Mul(dailyRate).Mul(dec128.FromInt64(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 14.024 33.683 9.975 6.569 35.116
udecimal.Decimal 23.302 41.854 12.226 11.346 40.877
alpacadecimal.Decimal 89.528 78.884 206.393 60.364 451.828
shopspring.Decimal 152.263 169.300 218.909 65.241 428.002
- Scale: Number of digits after the decimal point. For example, 1.00 has scale of 2 and 1.0000 has scale of 4.
- Exponent: Same as scale, 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.
- Quantum*: The smallest step at a given scale. For example, scale 2 has quantum 0.01
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.