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