Documentation
¶
Overview ¶
Package decimal implements a fixed-point decimal for financial values.
A Decimal is coefficient / 10^prec held by value: a 128-bit coefficient, at most nineteen fractional digits, no pointer, no allocation, nothing for the garbage collector to scan. Construction normalizes, so each value has exactly one representation and == is value equality.
The representable range trades precision against magnitude, because the two bounds bind together: the coefficient is at most 2^128−1 = 340282366920938463463374607431768211455 and prec is at most MaxFractionDigits. Carrying no fraction a value reaches ±340282366920938463463374607431768211455; carrying the full nineteen-digit fraction it reaches ±34028236692093846346.3374607431768211455; and the smallest nonzero magnitude is ±0.0000000000000000001. A result that does not fit is an error or a panic, never a slower fallback; this package does not reach for math/big.
Arithmetic is exact-or-panic: operations return the exact value or panic with ErrRange. Only parsing untrusted input (NewFromString) returns an error. Division alone rounds, matching shopspring/decimal: every quotient rounds half away from zero at sixteen fractional digits, so one that fits sixteen digits is exact.
The text and JSON forms are canonical decimal text: no exponent, no trailing fraction zeros, JSON quoted. The binary and gob form is this package's own compact layout; callers that persist it own their versioning.
Example ¶
package main
import (
"fmt"
"github.com/jankremlacek/decimal"
)
func main() {
price := decimal.MustFromString("64500.4")
qty := decimal.New(125, -2) // 1.25
total := price.Mul(qty)
fmt.Println(total)
fmt.Println(total.StringFixed(2))
share := total.Div(decimal.NewFromInt(3))
fmt.Println(share)
d, err := decimal.NewFromString("1.5e-8")
if err != nil {
panic(err)
}
fmt.Println(d, d.Cmp(decimal.Zero))
}
Output: 80625.5 80625.50 26875.1666666666666667 0.000000015 1
Index ¶
- Constants
- Variables
- type Decimal
- func Max(first Decimal, rest ...Decimal) Decimal
- func Min(first Decimal, rest ...Decimal) Decimal
- func MustFromString(v string) Decimal
- func New(v int64, exp int32) Decimal
- func NewFromFloat(v float64) Decimal
- func NewFromInt(v int64) Decimal
- func NewFromString(v string) (Decimal, error)
- func Sum(first Decimal, rest ...Decimal) Decimal
- func (d Decimal) Abs() Decimal
- func (d Decimal) Add(o Decimal) Decimal
- func (d Decimal) Append(b []byte) []byte
- func (d Decimal) Ceil() Decimal
- func (d Decimal) Cmp(o Decimal) int
- func (d Decimal) Div(o Decimal) Decimal
- func (d Decimal) Equal(o Decimal) bool
- func (d Decimal) Exponent() int32
- func (d Decimal) Floor() Decimal
- func (d *Decimal) GobDecode(data []byte) error
- func (d Decimal) GobEncode() ([]byte, error)
- func (d Decimal) GreaterThan(o Decimal) bool
- func (d Decimal) GreaterThanOrEqual(o Decimal) bool
- func (d Decimal) InexactFloat64() float64
- func (d Decimal) IsInteger() bool
- func (d Decimal) IsNegative() bool
- func (d Decimal) IsPositive() bool
- func (d Decimal) IsZero() bool
- func (d Decimal) LessThan(o Decimal) bool
- func (d Decimal) LessThanOrEqual(o Decimal) bool
- func (d Decimal) MarshalBinary() ([]byte, error)
- func (d Decimal) MarshalJSON() ([]byte, error)
- func (d Decimal) MarshalText() ([]byte, error)
- func (d Decimal) Mul(o Decimal) Decimal
- func (d Decimal) Neg() Decimal
- func (d Decimal) Round(places int32) Decimal
- func (d Decimal) RoundCeil(places int32) Decimal
- func (d Decimal) RoundFloor(places int32) Decimal
- func (d Decimal) RoundFloorSigFigs(sigFigs int32) Decimal
- func (d *Decimal) Scan(value any) error
- func (d Decimal) Sign() int
- func (d Decimal) String() string
- func (d Decimal) StringFixed(places int32) string
- func (d Decimal) Sub(o Decimal) Decimal
- func (d Decimal) TextLen() int
- func (d Decimal) Truncate(places int32) Decimal
- func (d *Decimal) UnmarshalBinary(data []byte) error
- func (d *Decimal) UnmarshalJSON(b []byte) error
- func (d *Decimal) UnmarshalText(text []byte) error
- func (d Decimal) Value() (driver.Value, error)
Examples ¶
Constants ¶
const MaxDigits = 39
MaxDigits is the longest coefficient a Decimal holds, in base-ten digits: 2^128−1 has 39. Not every 39-digit coefficient fits.
const MaxFractionDigits = 19
MaxFractionDigits is the widest fraction a Decimal holds: nineteen digits, so every scale factor fits a uint64, and wei (10^-18) is covered with a digit to spare.
Variables ¶
var ( // ErrSyntax reports text that does not spell a decimal. ErrSyntax = errors.New("decimal: invalid syntax") // ErrRange reports a value outside the 128-bit // coefficient or the nineteen-digit fraction. ErrRange = errors.New("decimal: out of range") // ErrDivByZero reports a zero divisor; [Decimal.Div] panics with it. ErrDivByZero = errors.New("decimal: division by zero") )
Functions ¶
This section is empty.
Types ¶
type Decimal ¶
type Decimal struct {
// contains filtered or unexported fields
}
Decimal is a signed fixed-point decimal: coefficient / 10^prec. The zero value is zero and ready to use.
A Decimal is immutable: every method returns a new value and never mutates its receiver or arguments, so a value is safe to copy and share.
Every value is normalized — the coefficient carries no trailing zeros and zero is never negative — so == compares values and Decimal keys maps.
func MustFromString ¶
MustFromString is NewFromString for text known to be well formed. It panics on anything else.
func New ¶
New returns v * 10^exp.
It panics when the result does not fit, which suits literals and constants; parse input that may be out of range with NewFromString.
func NewFromFloat ¶
NewFromFloat returns the decimal of the shortest text that round-trips to v, exactly as strconv.FormatFloat with precision -1 renders it.
It panics on NaN, an infinity, or a value needing more than nineteen fractional digits.
func NewFromInt ¶
NewFromInt returns v. Every int64 fits, so it never panics.
func NewFromString ¶
NewFromString parses decimal text: an optional sign, digits with an optional fraction, and an optional power-of-ten exponent, like "-1.5" or "1.5e-8". Either minus may also be U+2212 MINUS SIGN, as in "−1.5" or "1.5e−8". The error wraps ErrSyntax or ErrRange.
func Sum ¶
Sum returns the arguments added exactly, with Decimal.Add's panic on a sum that does not fit.
func (Decimal) Append ¶
Append writes what Decimal.String renders onto b, allocation-free.
func (Decimal) Div ¶
Div returns d / o rounded half away from zero at sixteen fractional digits, exactly as shopspring rounds. It panics with ErrDivByZero on a zero divisor, and with ErrRange when the quotient does not fit.
func (Decimal) Equal ¶
Equal reports whether d and o hold the same value. Canonical representation makes it plain ==.
func (Decimal) Exponent ¶
Exponent reports the power of ten the coefficient sits over: the negated fraction width of the canonical form, so zero or negative.
func (*Decimal) GobDecode ¶
GobDecode implements encoding/gob.GobDecoder as Decimal.UnmarshalBinary.
func (Decimal) GobEncode ¶
GobEncode implements encoding/gob.GobEncoder with the Decimal.MarshalBinary layout.
func (Decimal) GreaterThan ¶
GreaterThan reports whether d is greater than o.
func (Decimal) GreaterThanOrEqual ¶
GreaterThanOrEqual reports whether d is greater than or equal to o.
func (Decimal) InexactFloat64 ¶
InexactFloat64 reports the nearest float64, the name conceding what the conversion may cost.
func (Decimal) IsNegative ¶
IsNegative reports whether d < 0. Zero is never negative.
func (Decimal) IsPositive ¶
IsPositive reports whether d > 0, so false for zero.
func (Decimal) IsZero ¶
IsZero reports whether d is zero. Zero has one representation, so it is the same as d == Zero.
func (Decimal) LessThanOrEqual ¶
LessThanOrEqual reports whether d is less than or equal to o.
func (Decimal) MarshalBinary ¶
MarshalBinary implements encoding.BinaryMarshaler.
The layout is one header byte holding the precision with the sign in its top bit, then the coefficient as minimal big-endian bytes. Zero writes no coefficient bytes, so a decimal costs one byte at zero and seventeen at the full 128-bit width.
func (Decimal) MarshalJSON ¶
MarshalJSON implements encoding/json.Marshaler, writing the value as a JSON string. A decimal is quoted on the wire because a JSON number is a float to most readers, and that would lose the precision this type exists to keep.
func (Decimal) MarshalText ¶
MarshalText implements encoding.TextMarshaler.
func (Decimal) Mul ¶
Mul returns d * o exactly. It panics with ErrRange when the product does not fit — including a product whose nonzero fraction needs more than nineteen digits.
func (Decimal) Round ¶
Round returns d rounded half away from zero to places fraction digits. Negative places rounds left of the point: Round(-2) rounds to hundreds. It panics with ErrRange when that carries the result out of range.
func (Decimal) RoundCeil ¶
RoundCeil returns d rounded toward positive infinity to places fraction digits. Negative places and range behave as in Decimal.Round.
func (Decimal) RoundFloor ¶
RoundFloor returns d rounded toward negative infinity to places fraction digits. Negative places and range behave as in Decimal.Round.
func (Decimal) RoundFloorSigFigs ¶
RoundFloorSigFigs returns d rounded toward negative infinity to sigFigs significant figures. Zero is zero. Panics on sigFigs < 1.
A floor across a power of ten may carry one figure more than asked: -99999.5 at five figures is -100000. A floor that leaves the range panics with ErrRange.
func (*Decimal) Scan ¶
Scan implements sql.Scanner, accepting the driver shapes a numeric column arrives as: text raw or with one pair of surrounding quotes, an int64, or a float64. Unlike the constructors, a bad value fails the scan with an error — this is a database boundary, never a panic site.
func (Decimal) String ¶
String renders the canonical text form: no exponent, no trailing fraction zeros.
func (Decimal) StringFixed ¶
StringFixed renders d rounded half away from zero to exactly places fraction digits, zero-padded. Negative places renders the rounded integer: 545 at places -1 is "550".
func (Decimal) Sub ¶
Sub returns d - o exactly. It panics with ErrRange when the difference does not fit.
func (Decimal) TextLen ¶
TextLen reports how many bytes Decimal.Append writes.
func (Decimal) Truncate ¶
Truncate returns d with the fraction cut to places digits, no rounding. Negative places cuts left of the point: Truncate(-2) of 5432 is 5400.
func (*Decimal) UnmarshalBinary ¶
UnmarshalBinary implements encoding.BinaryUnmarshaler. Foreign bytes spelling a non-canonical value normalize on the way in. It returns ErrSyntax for empty data and ErrRange for a precision or coefficient that does not fit.
func (*Decimal) UnmarshalJSON ¶
UnmarshalJSON implements encoding/json.Unmarshaler, accepting the quoted and the bare numeric form. A JSON null leaves the receiver untouched. On error the receiver is untouched too.
func (*Decimal) UnmarshalText ¶
UnmarshalText implements encoding.TextUnmarshaler. It accepts what NewFromString does and leaves the receiver untouched on error.