Arbitrary-precision fixed-point decimal numbers for Go, avoiding floating-point precision issues with support for arithmetic, rounding, serialization, and database integration.
All arithmetic methods return new Decimal values; Decimal is immutable.
// Add returns d + d2.
func (d Decimal) Add(d2 Decimal) Decimal
// Sub returns d - d2.
func (d Decimal) Sub(d2 Decimal) Decimal
// Mul returns d * d2.
func (d Decimal) Mul(d2 Decimal) Decimal
// Div returns d / d2. If not exact, uses DivisionPrecision digits after decimal point.
// Panics on division by zero.
func (d Decimal) Div(d2 Decimal) Decimal
// DivRound divides and rounds to a given precision (integer multiple of 10^(-precision)).
// For positive quotient, digit 5 rounds away from 0.
// For negative quotient, digit 5 rounds away from 0.
// precision < 0 is allowed.
func (d Decimal) DivRound(d2 Decimal, precision int32) Decimal
// QuoRem returns quotient q and remainder r such that:
// d = d2 * q + r
// q is an integer multiple of 10^(-precision)
// 0 <= r < abs(d2) * 10^(-precision) if d >= 0
// 0 >= r > -abs(d2) * 10^(-precision) if d < 0
// precision < 0 is allowed.
func (d Decimal) QuoRem(d2 Decimal, precision int32) (Decimal, Decimal)
// Mod returns d mod d2 (the remainder of d / d2).
func (d Decimal) Mod(d2 Decimal) Decimal
// Neg returns -d.
func (d Decimal) Neg() Decimal
// Abs returns the absolute value of d.
func (d Decimal) Abs() Decimal
// Shift shifts the decimal in base 10.
// Positive shift moves decimal point right (multiplies by 10^shift).
// Negative shift moves decimal point left (divides by 10^(-shift)).
// Equivalent to adding shift to the exponent.
func (d Decimal) Shift(shift int32) DecimalUsage:
a := decimal.NewFromFloat(10)
b := decimal.NewFromFloat(3)
a.Add(b) // 13
a.Sub(b) // 7
a.Mul(b) // 30
a.Div(b) // 3.3333333333333333 (16 places by default)
a.DivRound(b, 2) // 3.33
a.Mod(b) // 1
a.Neg() // -10
a.Abs() // 10
q, r := a.QuoRem(b, 0) // q=3, r=1
// a = b * q + r => 10 = 3 * 3 + 1
a.Shift(2) // 1000 (10 * 10^2)
a.Shift(-1) // 1 (10 * 10^-1)// Sum returns the combined total of the provided Decimals.
// Requires at least one argument.
func Sum(first Decimal, rest ...Decimal) Decimal
// Avg returns the average value of the provided Decimals.
// Requires at least one argument.
func Avg(first Decimal, rest ...Decimal) Decimal
// Max returns the largest Decimal from the arguments.
// Requires at least one argument.
// To call with a slice: Max(arr[0], arr[1:]...)
func Max(first Decimal, rest ...Decimal) Decimal
// Min returns the smallest Decimal from the arguments.
// Requires at least one argument.
// To call with a slice: Min(arr[0], arr[1:]...)
func Min(first Decimal, rest ...Decimal) Decimal
// RescalePair rescales two decimals to a common exponent
// (the minimum exponent of both decimals).
func RescalePair(d1 Decimal, d2 Decimal) (Decimal, Decimal)Usage:
a := decimal.NewFromFloat(1.5)
b := decimal.NewFromFloat(2.5)
c := decimal.NewFromFloat(3.0)
decimal.Sum(a, b, c) // 7.0
decimal.Avg(a, b, c) // 2.333...
decimal.Max(a, b, c) // 3.0
decimal.Min(a, b, c) // 1.5
// With a slice
values := []decimal.Decimal{a, b, c}
decimal.Max(values[0], values[1:]...)
// RescalePair: align exponents
d1 := decimal.NewFromFloat(1.5) // exp: -1
d2 := decimal.NewFromFloat(2.50) // exp: -2
r1, r2 := decimal.RescalePair(d1, d2)
// Both will have exp=-2: r1="1.50", r2="2.50"// Pow returns d to the power of d2.
// When exponent is negative, uses PowPrecisionNegativeExponent for precision.
// Returns 0 (zero-value) for edge cases instead of error:
// - 0 ** 0 => undefined (returns 0)
// - 0 ** y where y < 0 => infinity (returns 0)
// - x ** y where x < 0 and y is non-integer => imaginary (returns 0)
// Use PowWithPrecision for error handling of edge cases.
func (d Decimal) Pow(d2 Decimal) Decimal
// PowInt32 returns d to the power of exp (int32).
// Only returns error when d=0 and exp=0 (undefined).
// When exponent is negative, uses PowPrecisionNegativeExponent for precision.
func (d Decimal) PowInt32(exp int32) (Decimal, error)
// PowBigInt returns d to the power of exp (*big.Int).
// Only returns error when d=0 and exp=0 (undefined).
// When exponent is negative, uses PowPrecisionNegativeExponent for precision.
func (d Decimal) PowBigInt(exp *big.Int) (Decimal, error)
// PowWithPrecision returns d to the power of d2 with minimum precision.
// precision specifies minimum digits after decimal point in result.
// Result is not rounded to precision places.
// Returns error for:
// - 0 ** 0 => undefined
// - 0 ** y where y < 0 => infinity
// - x ** y where x < 0 and y is non-integer => imaginary
func (d Decimal) PowWithPrecision(d2 Decimal, precision int32) (Decimal, error)Usage:
import "math/big"
// Simple power
d1 := decimal.NewFromFloat(4.0)
d2 := decimal.NewFromFloat(4.0)
d1.Pow(d2).String() // "256"
d3 := decimal.NewFromFloat(5.0)
d4 := decimal.NewFromFloat(5.73)
d3.Pow(d4).String() // "10118.08037125"
// Integer exponent
res, err := decimal.NewFromFloat(4.0).PowInt32(4)
res.String() // "256"
res2, err := decimal.NewFromFloat(3.13).PowInt32(5)
res2.String() // "300.4150512793"
// Negative exponent
res3, err := decimal.NewFromFloat(15.2).PowInt32(-2)
res3.String() // "0.0043282548476454"
// big.Int exponent
res4, err := decimal.NewFromFloat(3.0).PowBigInt(big.NewInt(3))
res4.String() // "27"
// With precision control
res5, err := decimal.NewFromFloat(5.0).PowWithPrecision(
decimal.NewFromFloat(5.73), 5,
)
res5.String() // "10118.080371595015625"// ExpHullAbrham calculates e^d using the Hull-Abraham algorithm.
// overallPrecision is the total precision (integer digits + decimal digits).
// Faster than ExpTaylor for small precision values.
// Uses ExpMaxIterations for iteration limit.
func (d Decimal) ExpHullAbrham(overallPrecision uint32) (Decimal, error)
// ExpTaylor calculates e^d using the Taylor series expansion.
// precision is the number of digits after the decimal point.
// Faster than ExpHullAbrham for large precision values.
func (d Decimal) ExpTaylor(precision int32) (Decimal, error)Usage:
// e^1 ≈ 2.71828...
d := decimal.NewFromInt(1)
// Hull-Abraham: overall precision of 10 digits total
result, err := d.ExpHullAbrham(10)
// result ≈ 2.718281828
// Taylor: 10 digits after decimal point
result2, err := d.ExpTaylor(10)
// result2 ≈ 2.7182818284// Ln calculates the natural logarithm of d.
// precision is the number of digits after the decimal point.
// Returns error for d <= 0.
func (d Decimal) Ln(precision int32) (Decimal, error)Usage:
// ln(2.71828...) ≈ 1.0
e, _ := decimal.NewFromInt(1).ExpTaylor(20)
result, err := e.Ln(10)
// result ≈ 1.0000000000
// ln(10) ≈ 2.302585...
ten := decimal.NewFromInt(10)
result2, err := ten.Ln(15)All trigonometric functions operate on radian values.
// Sin returns the sine of d (radian argument).
func (d Decimal) Sin() Decimal
// Cos returns the cosine of d (radian argument).
func (d Decimal) Cos() Decimal
// Tan returns the tangent of d (radian argument).
func (d Decimal) Tan() Decimal
// Atan returns the arctangent of d in radians.
func (d Decimal) Atan() DecimalUsage:
import "math"
// sin(π/6) = 0.5
piOver6 := decimal.NewFromFloat(math.Pi / 6)
piOver6.Sin().String() // approximately "0.5"
// cos(0) = 1
decimal.NewFromInt(0).Cos().String() // "1"
// tan(π/4) = 1
piOver4 := decimal.NewFromFloat(math.Pi / 4)
piOver4.Tan().String() // approximately "1"
// atan(1) = π/4
decimal.NewFromInt(1).Atan().String() // approximately "0.7853981633974483"Install with Tessl CLI
npx tessl i tessl/golang-github-com-shopspring--decimal@1.4.1