Skip to content

jokruger/dec128

Repository files navigation

dec128

Go Reference Go Report Card codecov Mentioned in Awesome Go

High performance 128-bit fixed-point decimal numbers in go.

Key Objectives / Features

  • 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")

Install

Run go get github.com/jokruger/dec128

Requirements

This library requires Go version >=1.23

Documentation

http://godoc.org/github.com/jokruger/dec128

Usage

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()) }

Why not use other libraries?

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.

Benchmarks

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 

Notes on Terminology

  • 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

License

This project is licensed under the MIT License. See the LICENSE file for details.

Attribution

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.

About

High performance 128-bit fixed-point decimal numbers in go.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages