Documentation
¶
Overview ¶
Package bigdecimal is a pure-Go (no cgo) reimplementation of Ruby's BigDecimal: arbitrary-precision decimal arithmetic and MRI-byte-exact formatting. It is the decimal backend for go-embedded-ruby, but a standalone, reusable module — a sibling of go-ruby-regexp, go-ruby-erb and go-ruby-yaml.
A Decimal is sign + significand (an arbitrary-precision integer) + a base-ten exponent, plus the three IEEE-style specials NaN / +Infinity / -Infinity that MRI's BigDecimal carries. The underlying integer math uses math/big; the decimal semantics — the canonical 0.15e1 scientific to_s, the rounding modes, floor/ceil/truncate at an arbitrary digit, div with an explicit precision, divmod/modulo/remainder, and the to_s("F"/"E"/"+"/" "/"N") format grammar — are this package's own, ported from MRI 4.0.5.
Index ¶
- Variables
- type Decimal
- func (d *Decimal) Abs() *Decimal
- func (d *Decimal) Add(o *Decimal) *Decimal
- func (d *Decimal) Ceil(n int) *Decimal
- func (d *Decimal) Cmp(o *Decimal) int
- func (d *Decimal) Div(o *Decimal, prec int) *Decimal
- func (d *Decimal) DivE(o *Decimal, prec int) (*Decimal, error)
- func (d *Decimal) DivMod(o *Decimal) (q, r *Decimal, err error)
- func (d *Decimal) Equal(o *Decimal) bool
- func (d *Decimal) Exponent() int
- func (d *Decimal) Fix() *Decimal
- func (d *Decimal) Float64() float64
- func (d *Decimal) Floor(n int) *Decimal
- func (d *Decimal) Frac() *Decimal
- func (d *Decimal) IDiv(o *Decimal) (*Decimal, error)
- func (d *Decimal) Int() *big.Int
- func (d *Decimal) IsFinite() bool
- func (d *Decimal) IsInfinite() int
- func (d *Decimal) IsNaN() bool
- func (d *Decimal) IsZero() bool
- func (d *Decimal) Mod(o *Decimal) (*Decimal, error)
- func (d *Decimal) Mul(o *Decimal) *Decimal
- func (d *Decimal) Neg() *Decimal
- func (d *Decimal) Pow(n int) *Decimal
- func (d *Decimal) Precision() int
- func (d *Decimal) Rat() *big.Rat
- func (d *Decimal) Remainder(o *Decimal) (*Decimal, error)
- func (d *Decimal) Round(n int, mode RoundMode) *Decimal
- func (d *Decimal) Sign() int
- func (d *Decimal) SplitParts() (sign int, digits string, base, exp int)
- func (d *Decimal) String() string
- func (d *Decimal) Sub(o *Decimal) *Decimal
- func (d *Decimal) ToS(format string) string
- func (d *Decimal) Truncate(n int) *Decimal
- type Option
- type RoundMode
Constants ¶
This section is empty.
Variables ¶
var ( // ErrSyntax is returned by New for a string that is not a BigDecimal literal. ErrSyntax = errors.New("invalid BigDecimal value") // ErrZeroDivision is returned by the fallible division/modulo helpers for a // finite-by-zero operation (MRI raises ZeroDivisionError). ErrZeroDivision = errors.New("divided by 0") )
Functions ¶
This section is empty.
Types ¶
type Decimal ¶
type Decimal struct {
// contains filtered or unexported fields
}
Decimal is an arbitrary-precision decimal: value = sign * coef * 10**exp for a finite number, where coef is a non-negative significand. The zero Decimal is not valid; build values through New / FromInt / FromBigInt.
A finite value is kept normalised so that coef has no trailing factor of ten (coef == 0 ⇒ exp == 0), which makes the canonical scientific to_s and equality independent of how the value was written. sign is +1 or -1 (a zero keeps the sign it was parsed with, mirroring MRI's distinct +0.0 / -0.0).
func FromBigInt ¶
FromBigInt builds a Decimal from an arbitrary-precision integer.
func FromFloat ¶
FromFloat builds a Decimal from a float64 limited to n significant digits, the MRI BigDecimal(Float, n) case (n must be > 0; MRI requires the precision for a Float argument). It renders the float with n significant digits and reparses, so 0.1 with n digits is the n-digit decimal nearest the binary float.
func New ¶
New parses a BigDecimal literal — the MRI BigDecimal("…") constructor for a String. It accepts an optional leading sign, a decimal mantissa with an optional fraction and an optional "e"/"E"/"d"/"D" exponent, plus the specials "NaN", "Infinity"/"+Infinity"/"-Infinity" (and MRI's tolerated leading/trailing blanks and an underscore digit separator). With WithDigits(n) the result is rounded to n significant digits. An unparseable string returns ErrSyntax.
func (*Decimal) Add ¶
Add returns d + o (BigDecimal#+). Special-value combinations follow MRI: NaN propagates, ∞+∞ stays ∞, ∞+(−∞) is NaN.
func (*Decimal) Ceil ¶
Ceil returns the value rounded toward +Infinity to n places (BigDecimal#ceil(n)).
func (*Decimal) Cmp ¶
Cmp compares d and o, returning -1, 0 or 1 (BigDecimal#<=>). It returns -2 to signal "incomparable" when either operand is NaN (MRI's <=> yields nil there); callers map -2 to nil.
func (*Decimal) Div ¶
Div returns d / o rounded to prec significant digits (BigDecimal#div(o, prec) / the bare BigDecimal#/). When prec > 0 the quotient carries exactly that many significant digits, half-up; when prec <= 0 it is computed exactly if the division terminates and otherwise to an MRI-style default working precision.
Division by a finite zero, or any NaN operand, yields the matching special (the caller decides whether that is an error); see DivE for the fallible form.
func (*Decimal) DivE ¶
DivE is Div with an explicit error for finite-by-zero (ErrZeroDivision), mirroring MRI raising ZeroDivisionError. Special operands still return the matching special with a nil error (∞ / 2, NaN / 1, …).
func (*Decimal) DivMod ¶
DivMod returns the floored quotient and the modulo (BigDecimal#divmod): q is floor(d/o) and r is d - q*o, so r has the sign of o.
func (*Decimal) Equal ¶
Equal reports value equality (BigDecimal#==). NaN is unequal to everything, including itself.
func (*Decimal) Exponent ¶
Exponent returns MRI's BigDecimal#exponent: the power of ten n such that the value equals 0.<digits> * 10**n. A zero or non-finite value returns 0.
func (*Decimal) Float64 ¶
Float64 returns the nearest float64 (BigDecimal#to_f). NaN/±Infinity map to the matching IEEE value.
func (*Decimal) Floor ¶
Floor returns the value rounded toward -Infinity to n places (BigDecimal#floor(n)).
func (*Decimal) Frac ¶
Frac returns the fractional part (BigDecimal#frac): the value with its integer part removed, keeping the sign. A special returns itself.
func (*Decimal) IDiv ¶
IDiv returns the integer quotient floor(d / o) as a Decimal (BigDecimal#div with no precision argument): the largest integer not greater than the exact quotient. NaN/∞/zero follow MRI; finite-by-zero returns NaN with ErrZeroDivision.
func (*Decimal) Int ¶
Int returns the value truncated toward zero as a *big.Int (BigDecimal#to_i). A NaN or ±Infinity returns nil (MRI raises; the caller decides).
func (*Decimal) IsInfinite ¶
IsInfinite reports whether the value is ±Infinity; +1 for +Inf, -1 for -Inf, 0 for a finite value or NaN (matching MRI's Float#infinite? / BigDecimal#infinite?).
func (*Decimal) Mod ¶
Mod returns the floored modulo d % o (BigDecimal#% / #modulo): the remainder with the sign of o.
func (*Decimal) Neg ¶
Neg returns -d (unary minus). A non-NaN value flips sign (including a signed zero, mirroring MRI's distinct +0.0 / −0.0); NaN is unchanged.
func (*Decimal) Pow ¶
Pow returns d ** n for an integer exponent (BigDecimal#** / #power). A negative exponent yields the reciprocal (to the default division precision); 0**0 is 1; 0 raised to a negative power returns +Infinity (as MRI does).
func (*Decimal) Precision ¶
Precision returns the number of significant decimal digits (MRI 4.0's BigDecimal#precision). A zero returns 0; a non-finite value returns 0.
func (*Decimal) Rat ¶
Rat returns the exact value as a *big.Rat (BigDecimal#to_r). A non-finite value returns nil.
func (*Decimal) Remainder ¶
Remainder returns the truncated remainder d.remainder(o): d - o*trunc(d/o), so it has the sign of d (unlike Mod, which has the sign of o).
func (*Decimal) Round ¶
Round returns the value rounded to n decimal places under mode (BigDecimal#round(n, mode)). n > 0 keeps n fractional digits, n == 0 rounds to an integer, n < 0 rounds away |n| whole digits.
func (*Decimal) Sign ¶
Sign returns MRI's BigDecimal#sign code: 0 for NaN, 1/-1 for ±0, 2/-2 for a finite non-zero, 3/-3 for ±Infinity.
func (*Decimal) SplitParts ¶
SplitParts implements BigDecimal#split: it returns the sign (1/-1, or 0 for NaN), the significant-digit string, the base (always 10) and the point exponent, so the value is sign * ("0." + digits).to_f * 10**exp. For a special the digit string is "NaN" / "Infinity" and exp is 0 (matching MRI).
func (*Decimal) String ¶
String renders the value in MRI's default BigDecimal#to_s form: the canonical scientific notation 0.<digits>e<exp> (so BigDecimal("1.5").to_s is "0.15e1").
func (*Decimal) ToS ¶
ToS renders the value under MRI's BigDecimal#to_s(fmt) grammar. The format string carries, in order:
- an optional leading sign flag: '+' prefixes non-negative values with '+', a space prefixes them with ' ' (a negative value always shows '-');
- an optional run of digits N, which groups the significant digits in blocks of N (separated by a space) — the integer part from the right and the fraction from the left;
- an optional 'F'/'f' selecting the plain floating form (e.g. "1234.5"), or 'E'/'e' / nothing selecting the scientific form 0.<digits>e<exp>.
The classic forms are ToS("") / ToS("E") (scientific), ToS("F") (plain), ToS("+") / ToS(" ") (sign prefix) and ToS("5F") (5-digit grouping).
type Option ¶
type Option func(*config)
Option configures New; the variadic mirrors BigDecimal(value, ndigits)'s optional significant-digit limit.
func WithDigits ¶
WithDigits limits a constructed value to n significant digits, as MRI's BigDecimal(value, n) does. n == 0 means "as many digits as the input has".
type RoundMode ¶
type RoundMode int
RoundMode selects how Round (and the precision-limited Div) breaks a tie or drops digits — the BigDecimal::ROUND_* family.
const ( // RoundUp rounds away from zero (ROUND_UP). RoundUp RoundMode = iota // RoundDown truncates toward zero (ROUND_DOWN). RoundDown // RoundHalfUp rounds a tie away from zero (ROUND_HALF_UP) — the default. RoundHalfUp // RoundHalfEven rounds a tie to the even neighbour (ROUND_HALF_EVEN, banker's). RoundHalfEven // RoundHalfDown rounds a tie toward zero (ROUND_HALF_DOWN). RoundHalfDown // RoundCeiling rounds toward +Infinity (ROUND_CEILING). RoundCeiling // RoundFloor rounds toward -Infinity (ROUND_FLOOR). RoundFloor )
