Documentation ¶
Overview ¶
Package decimal provides a high-performance, arbitrary precision, fixed-point decimal library.
The following type is supported:
Big decimal numbers
The zero value for a Big corresponds with 0. Its method naming is the same as math/big's, meaning:
func (z *T) SetV(v V) *T // z = v func (z *T) Unary(x *T) *T // z = unary x func (z *T) Binary(x, y *T) *T // z = x binary y func (x *T) Pred() P // p = pred(x)
In general, its conventions will mirror math/big's.
In general, operations that use the receiver z as storage will not modify z's Context. Additionally, the arguments to Binary and Unary methods are allowed to alias, so the following is valid:
x := New(1, 0) x.Add(x, x) // x == 2
Compared to other decimal libraries, this package:
- Has signals and traps, but only if you want them
- Only has mutable decimals (for efficiency's sake)
Index ¶
- Constants
- Variables
- func Raw(x *Big) (int64, *big.Int)
- type Big
- func (z *Big) Abs(x *Big) *Big
- func (z *Big) Add(x, y *Big) *Big
- func (x *Big) BitLen() int
- func (z *Big) Cmp(x *Big) int
- func (z *Big) Copy(x *Big) *Big
- func (x *Big) Float64() float64
- func (x *Big) Format(s fmt.State, c rune)
- func (x *Big) Int() *big.Int
- func (x *Big) Int64() int64
- func (x *Big) IsBig() bool
- func (x *Big) IsFinite() bool
- func (x *Big) IsInf(sign int) bool
- func (x *Big) IsInt() bool
- func (x *Big) IsNaN(signal int) bool
- func (x *Big) MarshalText() ([]byte, error)
- func (z *Big) Mul(x, y *Big) *Big
- func (z *Big) Neg(x *Big) *Big
- func (x *Big) Precision() int
- func (z *Big) Quo(x, y *Big) *Big
- func (z *Big) Round(n int32) *Big
- func (x *Big) Scale() int32
- func (z *Big) Set(x *Big) *Big
- func (z *Big) SetBigMantScale(value *big.Int, scale int32) *Big
- func (z *Big) SetFloat64(value float64) *Big
- func (x *Big) SetInf(signbit bool) *Big
- func (z *Big) SetMantScale(value int64, scale int32) *Big
- func (z *Big) SetNaN(signal bool) *Big
- func (z *Big) SetScale(scale int32) *Big
- func (z *Big) SetString(s string) (*Big, bool)
- func (x *Big) Sign() int
- func (x *Big) Signbit() bool
- func (x *Big) String() string
- func (z *Big) Sub(x, y *Big) *Big
- func (z *Big) UnmarshalText(data []byte) error
- type Condition
- type Context
- type ErrNaN
- type OperatingMode
- type RoundingMode
Examples ¶
Constants ¶
const ( MaxScale = math.MaxInt32 // largest allowed scale. MinScale = math.MinInt32 // smallest allowed scale. MaxPrecision = math.MaxInt32 // largest allowed Context precision. MinPrecision = 1 // smallest allowed Context precision. )
Precision and scale limits.
const DefaultPrecision = 16
DefaultPrecision is the default precision used for decimals created as literals or using new.
Variables ¶
var ( // Context32 is the IEEE 754R Decimal32 format. Context32 = Context{ RoundingMode: ToNearestEven, OperatingMode: GDA, Traps: ^(Inexact | Rounded | Subnormal), // contains filtered or unexported fields } // Context64 is the IEEE 754R Decimal64 format. Context64 = Context{ RoundingMode: ToNearestEven, OperatingMode: GDA, Traps: ^(Inexact | Rounded | Subnormal), // contains filtered or unexported fields } // Context128 is the IEEE 754R Decimal128 format. Context128 = Context{ RoundingMode: ToNearestEven, OperatingMode: GDA, Traps: ^(Inexact | Rounded | Subnormal), // contains filtered or unexported fields } )
The following Contexts are based on IEEE 754R. Context is exported for this documentation but is not expected to be used itself. Each Context's RoundingMode is ToNearestEven, OperatingMode is GDA, and traps are set to every exception other than Inexact, Rounded, and Subnormal.
var Regexp = regexp.MustCompile(`(?i)(((\+|-)?(\d+\.\d*|\.?\d+)([eE][+-]?\d+)?)|(inf(infinity)?))|((\+|-)?([sq]?nan))`)
Regexp matches any valid string representing a decimal that can be pased to SetString.
Functions ¶
func Raw ¶
Raw directly returns x's raw compact and unscaled values. Caveat emptor: Neither are guaranteed to be valid. Raw is intended to support missing functionality outside this package and generally should be avoided. Additionally, Raw is the only part of this package's API which is not guaranteed to remain stable. This means the function could change or disappear at any time, even across minor version numbers.
Types ¶
type Big ¶
type Big struct { // Context is the decimal's unique contextual object. Context Context // contains filtered or unexported fields }
Big is a fixed-point, arbitrary-precision decimal number.
A Big decimal is a number and a scale, the latter representing the number of digits following the radix if the scale is >= 0. Otherwise, it's the number * 10 ^ -scale.
Example (ReversePolishNotationCalculator) ¶
const input = "15 7 1 1 + - / 3 * 2 1 1 + + - 5 * 3 / =" var stack []*Big for _, tok := range strings.Split(input, " ") { last := len(stack) - 1 switch tok { case "+": x := stack[last-1] x.Add(x, stack[last]) stack = stack[:last] case "-": x := stack[last-1] x.Sub(x, stack[last]) stack = stack[:last] case "/": x := stack[last-1] x.Quo(x, stack[last]) stack = stack[:last] case "*": x := stack[last-1] x.Mul(x, stack[last]) stack = stack[:last] case "=": break default: x := new(Big) x.Context = Context128 if _, ok := x.SetString(tok); !ok { fmt.Fprintf(os.Stderr, "invalid decimal: %v\n", x.Context.Err) os.Exit(1) } stack = append(stack, x) } } fmt.Printf("%+6.4g\n", stack[0])
Output: +8.333
func New ¶
New creates a new Big decimal with the given value and scale. For example:
New(1234, 3) // 1.234 New(42, 0) // 42 New(4321, 5) // 0.04321 New(-1, 0) // -1 New(3, -10) // 30 000 000 000
func (*Big) BitLen ¶
BitLen returns the absolute value of x in bits. The result is undefined if x is an infinity or not a number value.
func (*Big) Cmp ¶
Cmp compares d and x and returns:
-1 if z < x 0 if z == x +1 if z > x
It does not modify z or x. The result is undefined if either z or x are not a number values.
func (*Big) Format ¶
Format implements the fmt.Formatter interface. The following verbs are supported:
%s: -dddd.dd or -d.dddd±edd, depending on x %d: same as %s %v: same as %s %e: -d.dddd±edd %E: -d.dddd±Edd %f: -dddd.dd %g: same as %f
Precision and width are honored in the same manner as the fmt package. In short, width is the minimum width of the formatted number. Given %f, precision is the number of digits following the radix. Given %g, precision is the number of significant digits.
Format honors all flags (such as '+' and ' ') in the same manner as the fmt package, except for '#'. Unless used in conjunction with %v, %q, or %p, the '#' flag will be ignored; decimals have no defined hexadeximal or octal representation.
%+v, %#v, %T, %#p, and %p all honor the formats specified in the fmt package's documentation.
func (*Big) Int ¶
Int returns x as a big.Int, truncating the fractional portion, if any. If x is an infinity or a not a number value the result is undefined.
func (*Big) Int64 ¶
Int64 returns x as an int64, truncating the fractional portion, if any. The result is undefined if x is an infinity, a not a number value, or if x does not fit inside an int64.
func (*Big) IsBig ¶
IsBig returns true if x, with its fractional part truncated, cannot fit inside an int64. If x is an infinity or a not a number value the result is undefined.
func (*Big) IsInf ¶
IsInf returns true if x is an infinity according to sign. If sign > 0, IsInf reports whether x is positive infinity. If sign < 0, IsInf reports whether x is negative infinity. If sign == 0, IsInf reports whether x is either infinity.
func (*Big) IsNaN ¶
IsNaN returns true if x is NaN. If sign > 0, IsNaN reports whether x is signaling NaN. If sign < 0, IsNaN reports whether x is quiet NaN. If sign == 0, IsNaN reports whether x is either NaN.
func (*Big) MarshalText ¶
MarshalText implements encoding/TextMarshaler.
func (*Big) Neg ¶
Neg sets z to -x and returns z. If x is positive infinity, z will be set to negative infinity and visa versa. If x == 0, z will be set to zero as well. NaN has no negative representation, and will result in an error.
func (*Big) Precision ¶
Precision returns the precision of x. That is, it returns the number of digits in the unscaled form of x. x == 0 has a precision of 1. The result is undefined if x is an infinity or a not a number value.
Example ¶
a := New(12, 0) b := New(42, -2) c := New(12345, 3) d := New(3, 5) fmt.Printf(` %s has a precision of %d %s has a precision of %d %s has a precision of %d %s has a precision of %d `, a, a.Precision(), b, b.Precision(), c, c.Precision(), d, d.Precision())
Output: 12 has a precision of 2 4.2e+3 has a precision of 2 12.345 has a precision of 5 0.00003 has a precision of 1
func (*Big) Round ¶
Round rounds z down to n digits of precision and returns z. The result is undefined if n < 0 or z is not finite. No rounding will occur if n == 0. The result of Round will always be within the interval [⌊z⌋, z].
Example ¶
a := New(1234, 0).Round(2) b := New(544, 1).Round(2) c := New(60, 0).Round(5) fmt.Println(a) fmt.Println(b) fmt.Println(c)
Output: 1.2e+3 54 60
func (*Big) Set ¶
Set sets z to x and returns z. The result might be rounded depending on z's Context.
func (*Big) SetBigMantScale ¶
SetBigMantScale sets z to the given value and scale.
func (*Big) SetFloat64 ¶
SetFloat64 sets z to the provided float64.
Because certain numbers cannot be exactly represented as floating-point numbers, SetFloat64 "rounds" its input in order to break it into simple mantissa and scale parts as if SetMantScale were called. If SetFloat64 took its input as-is, the result of calling SetFloat64(0.1) would be 0.1000000000000000055511151231257827021181583404541015625.
Approximately 2.3% of decimals created from floats will have an rounding imprecision of ± 1 ULP.
func (*Big) SetInf ¶
SetInf sets x to -Inf if signbit is set or +Inf is signbit is not set, and returns x.
func (*Big) SetMantScale ¶
SetMantScale sets z to the given value and scale.
func (*Big) SetNaN ¶
SetNaN sets z to a signaling NaN if signal is true or quiet NaN otherwise and returns z.
func (*Big) SetString ¶
SetString sets z to the value of s, returning z and a bool indicating success. s must be a string in one of the following formats:
1.234 1234 1.234e+5 1.234E-5 0.000001234 Inf +Inf -Inf NaN qNaN sNaN
Inf and NaN map to +Inf and qNaN, respectively. NaN values may have optional diagnostic information, represented as trailing digits; for example, “NaN123”. These digits are otherwise ignored but are included for robustness.
func (*Big) Sign ¶
Sign returns:
-1 if x < 0 0 if x == 0 +1 if x > 0
The result is undefined if x is a not a number value.
func (*Big) String ¶
String returns the string representation of x. It's equivalent to the %s verb discussed in the Format method's documentation. Special cases depend on the OperatingMode. The defaults (for OperatingMode == Go) are:
"<nil>" if x == nil "+Inf" if x.IsInf(+1) "+Inf" if x.IsInf(0) "-Inf" if x.IsInf(-1)
func (*Big) UnmarshalText ¶
UnmarshalText implements encoding/TextUnmarshaler.
type Condition ¶
type Condition uint32
Condition is a bitmask value raised after or during specific operations. For example, dividing by zero is undefined so a DivisionByZero Condition flag will be set in the decimal's Context.
const ( // Clamped occurs if the scale has been modified to fit the constraints of // the decimal representation. Clamped Condition = 1 << iota // ConversionSyntax occurs when a string is converted to a decimal and does // not have a valid syntax. ConversionSyntax // DivisionByZero occurs when division is attempted with a finite, // non-zero dividend and a divisor with a value of zero. DivisionByZero // DivisionImpossible occurs when the result of integer division would // contain too many digits (i.e. be longer than the specified precision). DivisionImpossible // DivisionUndefined occurs when division is attempted with in which both // the divided and divisor are zero. DivisionUndefined // Inexact occurs when the result of an operation (e.g. division) is not // exact, or when the Overflow/Underflow Conditions occur. Inexact // InsufficientStorage occurs when the system doesn't have enough storage // (i.e. memory) to store the decimal. InsufficientStorage // InvalidContext occurs when an invalid context was detected during an // operation. This might occur if, for example, an invalid RoundingMode was // passed to a Context. InvalidContext // InvalidOperation occurs when: // // - an operand to an operation is a signaling NaN // - an attempt is made to add or subtract infinities of opposite signs // - an attempt is made to multiply zero by an infinity of either sign // - an attempt is made to divide an infinity by an infinity // - the divisor for a remainder operation is zero // - the dividend for a remainder operation is an infinity // - either operand of the quantize operation is an infinity, or the result // of a quantize operation would require greater precision than is // available // - the operand of the ln or the log10 operation is less than zero // - the operand of the square-root operation has a sign of 1 and a // non-zero coefficient // - both operands of the power operation are zero, or if the left-hand // operand is less than zero and the right-hand operand does not have an // integral value or is an infinity // InvalidOperation // Overflow occurs when the adjusted scale, after rounding, would be // greater than MaxScale. (Inexact and Rounded will also be raised.) Overflow // Rounded occurs when the result of an operation is rounded, or if an // Overflow/Underflow occurs. Rounded // Subnormal ocurs when the result of a conversion or operation is subnormal // (i.e. the adjusted scale is less than MinScale before any rounding). Subnormal // Underflow occurs when the result is inexact and the adjusted scale would // be smaller (more negative) than MinScale. Underflow )
type Context ¶
type Context struct { // OperatingMode which dictates how the decimal operates. For example, the // Decimal Arithmetic Specification (version 1.70) requires an infinity // decimal, to return "Infinity" from its "String" (or equivalent) method. // This, however, differs from other Go types like float64 and big.Float // that return "+Inf" or "-Inf." To compensate, Context provides multiple // modes that so the client can choose a preferred mode. OperatingMode OperatingMode // Traps are a set of exceptional conditions that should result in an error. Traps Condition // Conditions are a set of the most recent exceptional conditions to occur // during an operation. Conditions Condition // Err is the most recent error to occur during an operation. Err error // RoundingMode instructs how an infinite (repeating) decimal expansion // (digits following the radix) should be rounded. This can occur during // "lossy" operations like division. RoundingMode RoundingMode // contains filtered or unexported fields }
Context is a per-decimal contextual object that governs specific operations such as how lossy operations (e.g. division) round.
func (*Context) SetPrecision ¶
SetPrecision sets c's precision.
type ErrNaN ¶
type ErrNaN struct { // TODO(eric): Perhaps use math/big.ErrNaN if possible in the future? Msg string }
An ErrNaN panic is raised by a decimal operation that would lead to a NaN under IEEE-754 rules. An ErrNaN implements the error interface.
type OperatingMode ¶
type OperatingMode uint8
OperatingMode dictates how the decimal approaches specific non-numeric operations like conversions to strings and panicking on NaNs. See Context's documentation for further information.
const ( // Go adheres to typical Go idioms. Go OperatingMode = iota // GDA strictly adheres to the General Decimal Arithmetic Specification // Version 1.70. GDA )
func (OperatingMode) String ¶
func (i OperatingMode) String() string
type RoundingMode ¶
type RoundingMode uint8
RoundingMode determines how a decimal will be rounded if the exact result cannot accurately be represented.
const ( ToNearestEven RoundingMode = iota // == IEEE 754-2008 roundTiesToEven ToNearestAway // == IEEE 754-2008 roundTiesToAway ToZero // == IEEE 754-2008 roundTowardZero AwayFromZero // no IEEE 754-2008 equivalent ToNegativeInf // == IEEE 754-2008 roundTowardNegative ToPositiveInf // == IEEE 754-2008 roundTowardPositive // Unneeded means finite decimal expansion. Lossy routines will panic if // this RoundingMode is provided and the lossy operation does not have a // finite decimal expansion. Unneeded )
The following rounding modes are supported.
func (RoundingMode) String ¶
func (i RoundingMode) String() string
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
internal
|
|
arith
Package arith provides simple, primarily bit-specific, arithmetic operations.
|
Package arith provides simple, primarily bit-specific, arithmetic operations. |
arith/checked
Package checked implements basic checked arithmetic.
|
Package checked implements basic checked arithmetic. |
arith/pow
Package pow implements basic power functions.
|
Package pow implements basic power functions. |
c
Package c provides basic, internal constants.
|
Package c provides basic, internal constants. |
Package math implements various useful mathematical functions and constants.
|
Package math implements various useful mathematical functions and constants. |
sql
|
|
postgres
Package postgres provides a simple wrapper around a decimal.Big type, allowing it to be used in PostgreSQL queries.
|
Package postgres provides a simple wrapper around a decimal.Big type, allowing it to be used in PostgreSQL queries. |
Package suite provides a simple API for parsing and using IBM Labs' "Floating-Point Test-Suite for IEEE"
|
Package suite provides a simple API for parsing and using IBM Labs' "Floating-Point Test-Suite for IEEE" |