Documentation ¶
Overview ¶
Package decimal provides a high-performance, arbitrary precision, floating-point decimal library.
Overview ¶
This package provides floating-point decimal numbers, useful for financial programming or calculations where a larger, more accurate representation of a number is required.
In addition to basic arithmetic operations (addition, subtraction, multiplication, and division) this package offers various mathematical functions, including the exponential function, various logarithms, and the ability to compute continued fractions.
While lean, this package is full of features. It implements interfaces like “fmt.Formatter” and intuitively utilizes verbs and flags as described in the “fmt” package. (Also included: “fmt.Scanner”, “fmt.Stringer”, “encoding.TextUnmarshaler”, and “encoding.TextMarshaler”.)
It allows users to specific explicit contexts for arithmetic operations, but doesn't require it. It provides access to NaN payloads and is more lenient when parsing a decimal from a string than the GDA specification requires.
API interfaces have been changed slightly to work more seamlessly with existing Go programs. For example, many “Quantize” implementations require a decimal as both the receiver and argument which isn't very user friendly. Instead, this library accepts a simple “int” which can be derived from an existing decimal if required.
It contains two modes of operation designed to make transitioning to various GDA "quirks" (like always rounding lossless operations) easier.
GDA: strictly adhere to the GDA specification (default) Go: utilize Go idioms, more flexibility
Goals ¶
There are three primary goals of this library:
- Correctness
By adhering to the General Decimal Arithmetic specification, this package has a well-defined structure for its arithmetic operations.
- Performance
Decimal libraries are inherently slow; this library works diligently to minimize memory allocations and utilize efficient algorithms. Performance regularly benchmarks as fast or faster than many other popular decimal libraries.
- Ease of use
Libraries should be intuitive and work out of the box without having to configure too many settings; however, precise settings should still be available.
Usage ¶
The following type is supported:
Big decimal numbers
The zero value for a Big corresponds with 0, meaning all the following are valid:
var x Big y := new(Big) z := &Big{}
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 mirror math/big's. It is suggested to read the math/big package comments to gain an understanding of this package's conventions.
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 y := New(1, 0) y.FMA(y, x, y) // y == 3
Unless otherwise specified, the only argument that will be modified is the result (“z”). This means the following is valid and race-free:
x := New(1, 0) var g1, g2 Big go func() { g1.Add(x, x) }() go func() { g2.Add(x, x) }()
But this is not:
x := New(1, 0) var g Big go func() { g.Add(x, x) }() // BAD! RACE CONDITION! go func() { g.Add(x, x) }() // BAD! RACE CONDITION!
Index ¶
- Constants
- Variables
- func Raw(x *Big) (*uint64, *big.Int)
- type Big
- func BinarySplit(z *Big, ctx Context, start, stop uint64, A, P, B, Q SplitFunc) *Big
- func BinarySplitDynamic(ctx Context, A, P, B, Q SplitFunc) *Big
- func Max(a, b *Big) *Big
- func MaxAbs(x ...*Big) *Big
- func Min(x ...*Big) *Big
- func MinAbs(x ...*Big) *Big
- func New(value int64, scale int) *Big
- func WithContext(c Context) *Big
- func WithPrecision(p int) *Big
- func (z *Big) Abs(x *Big) *Big
- func (z *Big) Add(x, y *Big) *Big
- func (z *Big) Canonical(x *Big) *Big
- func (z *Big) CheckNaNs(x, y *Big) bool
- func (x *Big) Class() string
- func (x *Big) Cmp(y *Big) int
- func (x *Big) CmpAbs(y *Big) int
- func (x *Big) CmpTotal(y *Big) int
- func (x *Big) CmpTotalAbs(y *Big) int
- func (z *Big) Compose(form byte, negative bool, coefficient []byte, exponent int32) error
- func (z *Big) Copy(x *Big) *Big
- func (z *Big) CopyAbs(x *Big) *Big
- func (z *Big) CopyNeg(x *Big) *Big
- func (z *Big) CopySign(x, y *Big) *Big
- func (z *Big) Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)
- func (z *Big) FMA(x, y, u *Big) *Big
- func (x *Big) Float(z *big.Float) *big.Float
- func (x *Big) Float64() (f float64, ok bool)
- func (x *Big) Format(s fmt.State, c rune)
- func (x *Big) Int(z *big.Int) *big.Int
- func (x *Big) Int64() (int64, bool)
- func (x *Big) IsFinite() bool
- func (x *Big) IsInf(sign int) bool
- func (x *Big) IsInt() bool
- func (x *Big) IsNaN(quiet int) bool
- func (x *Big) IsNormal() bool
- func (x *Big) IsSubnormal() bool
- func (x *Big) Mantissa() (uint64, 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) Payload() Payload
- func (x *Big) Precision() int
- func (z *Big) Quantize(n int) *Big
- func (z *Big) Quo(x, y *Big) *Big
- func (z *Big) QuoInt(x, y *Big) *Big
- func (z *Big) QuoRem(x, y, r *Big) (*Big, *Big)
- func (x *Big) Rat(z *big.Rat) *big.Rat
- func (z *Big) Reduce() *Big
- func (z *Big) Rem(x, y *Big) *Big
- func (z *Big) Round(n int) *Big
- func (z *Big) RoundToInt() *Big
- func (x *Big) SameQuantum(y *Big) bool
- func (x *Big) Scale() int
- func (z *Big) Scan(state fmt.ScanState, verb rune) error
- func (z *Big) Set(x *Big) *Big
- func (z *Big) SetBigMantScale(value *big.Int, scale int) *Big
- func (z *Big) SetFloat(x *big.Float) *Big
- func (z *Big) SetFloat64(x float64) *Big
- func (z *Big) SetInf(signbit bool) *Big
- func (z *Big) SetMantScale(value int64, scale int) *Big
- func (z *Big) SetNaN(signal bool) *Big
- func (z *Big) SetRat(x *big.Rat) *Big
- func (z *Big) SetScale(scale int) *Big
- func (z *Big) SetSignbit(sign bool) *Big
- func (z *Big) SetString(s string) (*Big, bool)
- func (z *Big) SetUint64(x uint64) *Big
- func (x *Big) Sign() int
- func (x *Big) Signbit() bool
- func (x *Big) String() string
- func (z *Big) Sub(x, y *Big) *Big
- func (x *Big) Uint64() (uint64, bool)
- func (z *Big) UnmarshalJSON(data []byte) error
- func (z *Big) UnmarshalText(data []byte) error
- type Condition
- type Context
- func (c Context) Abs(z, x *Big) *Big
- func (c Context) Acos(z, x *Big) *Big
- func (c Context) Add(z, x, y *Big) *Big
- func (c Context) Asin(z, x *Big) *Big
- func (c Context) Atan(z, x *Big) *Big
- func (c Context) Atan2(z, y, x *Big) *Big
- func (c Context) Ceil(z, x *Big) *Big
- func (c Context) Cos(z, x *Big) *Big
- func (c Context) E(z *Big) *Big
- func (c Context) Err() error
- func (c Context) Exp(z, x *Big) *Big
- func (c Context) FMA(z, x, y, u *Big) *Big
- func (c Context) Floor(z, x *Big) *Big
- func (c Context) Hypot(z, p, q *Big) *Big
- func (c Context) Lentz(z *Big, g Generator) *Big
- func (c Context) Log(z, x *Big) *Big
- func (c Context) Log10(z, x *Big) *Big
- func (c Context) Mul(z, x, y *Big) *Big
- func (c Context) Neg(z, x *Big) *Big
- func (c Context) NextMinus(z, x *Big) *Big
- func (c Context) NextPlus(z, x *Big) *Big
- func (c Context) Pi(z *Big) *Big
- func (c Context) Pow(z, x, y *Big) *Big
- func (c Context) Quantize(z *Big, n int) *Big
- func (c Context) Quo(z, x, y *Big) *Big
- func (c Context) QuoInt(z, x, y *Big) *Big
- func (c Context) QuoRem(z, x, y, r *Big) (*Big, *Big)
- func (c Context) Reduce(z *Big) *Big
- func (c Context) Rem(z, x, y *Big) *Big
- func (c Context) Round(z *Big) *Big
- func (c Context) RoundToInt(z *Big) *Big
- func (c Context) Set(z, x *Big) *Big
- func (c Context) SetRat(z *Big, x *big.Rat) *Big
- func (c Context) SetString(z *Big, s string) (*Big, bool)
- func (c Context) Sin(z, x *Big) *Big
- func (c Context) Sqrt(z, x *Big) *Big
- func (c Context) Sub(z, x, y *Big) *Big
- func (c Context) Tan(z, x *Big) *Big
- func (c Context) Wallis(z *Big, g Generator) *Big
- type Contexter
- type ErrNaN
- type Generator
- type Lentzer
- type OperatingMode
- type Payload
- type RoundingMode
- type SplitFunc
- type Term
- type Walliser
Examples ¶
Constants ¶
const ( // Radix is the base in which decimal arithmetic is // performed. Radix = 10 // IsCanonical is true since Big decimals are always // normalized. IsCanonical = true )
const ( MaxScale = c.MaxScale // largest allowed scale. MinScale = -MaxScale // smallest allowed scale. MaxPrecision = MaxScale // largest allowed Context precision. MinPrecision = 1 // smallest allowed Context precision. UnlimitedPrecision = MaxPrecision + 1 // no precision, but may error. DefaultPrecision = 16 // default precision for literals. )
Precision and scale limits.
Variables ¶
var ( // Context32 is the IEEE 754R Decimal32 format. Context32 = Context{ Precision: 7, RoundingMode: ToNearestEven, OperatingMode: GDA, Traps: ^(Inexact | Rounded | Subnormal), MaxScale: 96, MinScale: -95, } // Context64 is the IEEE 754R Decimal64 format. Context64 = Context{ Precision: 16, RoundingMode: ToNearestEven, OperatingMode: GDA, Traps: ^(Inexact | Rounded | Subnormal), MaxScale: 384, MinScale: -383, } // Context128 is the IEEE 754R Decimal128 format. Context128 = Context{ Precision: 34, RoundingMode: ToNearestEven, OperatingMode: GDA, Traps: ^(Inexact | Rounded | Subnormal), MaxScale: 6144, MinScale: -6143, } // ContextUnlimited provides unlimited precision decimals. ContextUnlimited = Context{ Precision: UnlimitedPrecision, RoundingMode: ToNearestEven, OperatingMode: GDA, Traps: ^(Inexact | Rounded | Subnormal), MaxScale: MaxScale, MinScale: MinScale, } )
The following Contexts are based on IEEE 754R. 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\d*))`)
Regexp matches any valid string representing a decimal that can be passed 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 should generally be avoided. Additionally, Raw is the only part of this package's API that 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 floating-point, arbitrary-precision
It is represented as a number and a scale. A scale greater than zero indicates the number of decimal digits after the radix. Otherwise, the number is multiplied by 10 to the power of the negation of the scale. More formally,
Big = number × 10**-scale
with MinScale <= scale <= MaxScale. A Big may also be ±0, ±Infinity, or ±NaN (either quiet or signaling). Non-NaN Big values are ordered, defined as the result of x.Cmp(y).
Additionally, each Big value has a contextual object which governs arithmetic operations.
Example (ReversePolishNotationCalculator) ¶
ctx := Context128 const input = "15 7 1 1 + - / 3 * 2 1 1 + + - 5 * 3 / =" var stack []*Big Loop: for _, tok := range strings.Split(input, " ") { last := len(stack) - 1 switch tok { case "+": x := stack[last-1] ctx.Add(x, x, stack[last]) stack = stack[:last] case "-": x := stack[last-1] ctx.Sub(x, x, stack[last]) stack = stack[:last] case "/": x := stack[last-1] ctx.Quo(x, x, stack[last]) stack = stack[:last] case "*": x := stack[last-1] ctx.Mul(x, x, stack[last]) stack = stack[:last] case "=": break Loop default: var x Big 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 BinarySplit ¶
BinarySplit sets z to the result of the binary splitting formula and returns z. The formula is defined as:
∞ a(n)p(0) ... p(n) S = Σ ------------------- n=0 b(n)q(0) ... q(n)
It should only be used when the number of terms is known ahead of time. If start is not in [start, stop) or stop is not in (start, stop], BinarySplit will panic.
func BinarySplitDynamic ¶
BinarySplitDynamic sets z to the result of the binary splitting formula. It should be used when the number of terms is not known ahead of time. For more information, See BinarySplit.
func Max ¶
Max returns the greater of the provided values.
The result is undefined if no values are are provided.
func MaxAbs ¶
MaxAbs returns the greater of the absolute value of the provided values.
The result is undefined if no values are provided.
func Min ¶
Min returns the lesser of the provided values.
The result is undefined if no values are are provided.
func MinAbs ¶
MinAbs returns the lesser of the absolute value of the provided values.
The result is undefined if no values are provided.
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 WithContext ¶
WithContext is shorthand to create a Big decimal from a Context.
func WithPrecision ¶
WithPrecision is shorthand to create a Big decimal with a given precision.
func (*Big) Canonical ¶
Canonical sets z to the canonical form of z.
Since Big values are always canonical, it's identical to Copy.
func (*Big) CheckNaNs ¶
CheckNaNs checks if either x or y is NaN.
If so, it follows the rules of NaN handling set forth in the GDA specification. The argument y may be nil. It reports whether either condition is a NaN.
func (*Big) Class ¶
Class returns the "class" of x, which is one of the following:
sNaN NaN -Infinity -Normal -Subnormal -Zero +Zero +Subnormal +Normal +Infinity
func (*Big) Cmp ¶
Cmp compares x and y and returns:
-1 if x < y 0 if x == y +1 if x > y
It does not modify x or y. The result is undefined if either x or y are NaN.
For an abstract comparison with NaN values, see CmpTotal.
func (*Big) CmpAbs ¶
CmpAbs compares |x| and |y| and returns:
-1 if |x| < |y| 0 if |x| == |y| +1 if |x| > |y|
It does not modify x or y. The result is undefined if either x or y are NaN.
For an abstract comparison with NaN values, see CmpTotalAbs.
func (*Big) CmpTotal ¶
CmpTotal compares x and y in a manner similar to the Big.Cmp, but allows ordering of all abstract representations.
In particular, this means NaN values have a defined ordering. From lowest to highest the ordering is:
-NaN -sNaN -Infinity -127 -1.00 -1 -0.000 -0 +0 +1.2300 +1.23 +1E+9 +Infinity +sNaN +NaN
func (*Big) CmpTotalAbs ¶
CmpTotalAbs is like CmpTotal but instead compares the absolute values of x and y.
func (*Big) Compose ¶
Compose sets the internal decimal value from parts. If the value cannot be represented then an error should be returned.
func (*Big) CopySign ¶
CopySign sets z to x with the sign of y and returns z.
It accepts NaN values.
func (*Big) Decompose ¶
Decompose returns the internal decimal state into parts. If the provided buf has sufficient capacity, buf may be returned as the coefficient with the value set and length set as appropriate.
func (*Big) Float ¶
Float sets z, which may be nil, to x and returns z.
The result is undefined if z is a NaN value.
func (*Big) Float64 ¶
Float64 returns x as a float64 and a bool indicating whether x can fit into a float64 without truncation, overflow, or underflow.
Special values are considered exact; however, special values that occur because the magnitude of x is too large to be represented as a float64 are not.
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
While width is honored in the same manner as the fmt package (the minimum width of the formatted number), precision is the number of significant digits in the decimal number. Given %f, however, precision is the number of digits following the radix.
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.
Example ¶
print := func(format, xs string) { x, _ := new(Big).SetString(xs) fmt.Printf(format+"\n", x) } print("%s", "12.34") print("%.3g", "12.34") print("%.1f", "12.34") print("`%6.4g`", "500.44") print("'%-10.f'", "-404.040")
Output: 12.34 12.3 12.3 ` 500.4` '-404 '
func (*Big) Int ¶
Int sets z, which may be nil, to x, truncating the fractional portion (if any) and returns z.
If x is an infinity or a NaN value the result is undefined.
func (*Big) Int64 ¶
Int64 returns x as an int64, truncating towards zero.
The bool result indicates whether the conversion to an int64 was successful.
func (*Big) IsInf ¶
IsInf reports whether 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) IsInt ¶
IsInt reports whether x is an integer.
Infinity and NaN values are not integers.
func (*Big) IsNaN ¶
IsNaN reports whether x is NaN. If sign > 0, IsNaN reports whether x is quiet NaN. If sign < 0, IsNaN reports whether x is signaling NaN. If sign == 0, IsNaN reports whether x is either NaN.
func (*Big) IsSubnormal ¶
IsSubnormal reports whether x is subnormal.
func (*Big) Mantissa ¶
Mantissa returns the mantissa of x and reports whether the mantissa fits into a uint64 and x is finite.
This may be used to convert a decimal representing a monetary value to its most basic unit (e.g., $123.45 to 12345 cents).
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 vice versa. If x == 0, z will be set to zero. It is an error if x is a NaN value
func (*Big) Payload ¶
Payload returns the payload of x, provided x is a NaN value.
If x is not a NaN value, the result is undefined.
func (*Big) Precision ¶
Precision 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 not finite.
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) Quantize ¶
Quantize sets z to the number equal in value and sign to z with the scale, n.
z is rounded according to z.Context.RoundingMode. To perform truncation, set z.Context.RoundingMode to ToZero.
Example ¶
a, _ := WithContext(Context32).SetString("2.17") b, _ := WithContext(Context64).SetString("217") c, _ := WithContext(Context128).SetString("-0.1") d, _ := WithContext(Context{OperatingMode: GDA}).SetString("-0") fmt.Printf("A: %s\n", a.Quantize(3)) // 3 digits after radix fmt.Printf("B: %s\n", b.Quantize(-2)) fmt.Printf("C: %s\n", c.Quantize(1)) fmt.Printf("D: %s\n", d.Quantize(-5))
Output: A: 2.170 B: 2E+2 C: -0.1 D: -0E+5
func (*Big) QuoInt ¶
QuoInt sets z to x / y with the remainder truncated. See QuoRem for more details.
func (*Big) QuoRem ¶
QuoRem sets z to the quotient x / y and r to the remainder x % y, such that x = z * y + r, and returns the pair (z, r).
func (*Big) Rat ¶
Rat sets z, which may be nil, to x and returns z.
The result is undefined if x is an infinity or NaN value.
func (*Big) Round ¶
Round rounds z down to n digits of precision and returns z.
The result is undefined if z is not finite. No rounding will occur if n <= 0. The result of Round will always be in the interval [⌊10**p⌋, z] where p = the precision of z.
Example ¶
a, _ := new(Big).SetString("1234") b, _ := new(Big).SetString("54.4") c, _ := new(Big).SetString("60") d, _ := new(Big).SetString("0.0022") fmt.Println(a.Round(2)) fmt.Println(b.Round(2)) fmt.Println(c.Round(5)) fmt.Println(d.Round(1))
Output: 1.2E+3 54 60 0.002
func (*Big) RoundToInt ¶
RoundToInt rounds z down to an integral value.
func (*Big) SameQuantum ¶
SameQuantum reports whether x and y have the same exponent (scale).
func (*Big) Set ¶
Set sets z to x and returns z.
The result might be rounded depending on z.Context, even if z == x.
func (*Big) SetBigMantScale ¶
SetBigMantScale sets z to the given value and scale.
func (*Big) SetInf ¶
SetInf sets z to -Inf if signbit is set or +Inf is signbit is not set, and returns z.
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.
No conditions are raised.
func (*Big) SetSignbit ¶
SetSignbit sets z to -z if sign is true, otherwise to +z.
func (*Big) SetString ¶
SetString sets z to the value of s and returns z.
s must have one of the following formats:
1.234 1234 1.234e+5 1.234E-5 0.000001234 Inf NaN qNaN sNaN
Each format may be preceded by an optional sign, either "-" or "+". By default, "Inf" and "NaN" map to "+Inf" and "qNaN", respectively. NaN values may have optional diagnostic information, represented as trailing digits; for example, "NaN123".
If s does not match one of the allowed formats, the ConversionSyntax condition is set.
SetString will only return (nil, false) if a library error occurs. In general, it safe to ignore the bool result.
func (*Big) Sign ¶
Sign returns:
-1 if x < 0 0 if x == 0 +1 if x > 0
No distinction is made between +0 and -0. The result is undefined if x is a NaN value.
func (*Big) Signbit ¶
Signbit reports whether x is negative, negative zero, negative infinity, or negative NaN.
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.
func (*Big) Uint64 ¶
Uint64 returns x as a uint64, truncating towards zero.
The bool result indicates whether the conversion to a uint64 was successful.
func (*Big) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.
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 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 { // MaxScale overrides the MaxScale constant so long as it's // in the range (0, MaxScale]. MaxScale int // MinScale overrides the MaxScale constant so long as it's // in the range [MinScale, 0). MinScale int // Precision is the Context's precision; that is, the maximum // number of significant digits that may result from any // arithmetic operation. Excluding any package-defined // constants (e.g., "UnlimitedPrecision"), if precision is // not in the range [1, MaxPrecision] operations might result // in an error. A precision of 0 will be interpreted as // DefaultPrecision. For example, // // precision == 4 // 4 // precision == -4 // error // precision == 0 // DefaultPrecision // precision == 12 // 12 // Precision int // 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 // RoundingMode determines how a decimal is rounded. RoundingMode RoundingMode // OperatingMode which dictates how the decimal operates under certain // conditions. See OperatingMode for more information. OperatingMode OperatingMode }
Context is a per-decimal contextual object that governs specific operations.
func (Context) Acos ¶
Acos returns the arccosine, in radians, of x.
Range:
Input: -1 <= x <= 1 Output: 0 <= Acos(x) <= pi
Special cases:
Acos(NaN) = NaN Acos(±Inf) = NaN Acos(x) = NaN if x < -1 or x > 1 Acos(-1) = pi Acos(1) = 0
func (Context) Asin ¶
Asin returns the arcsine, in radians, of x.
Range:
Input: -1 <= x <= 1 Output: -pi/2 <= Asin(x) <= pi/2
Special cases:
Asin(NaN) = NaN Asin(±Inf) = NaN Asin(x) = NaN if x < -1 or x > 1 Asin(±1) = ±pi/2
func (Context) Atan ¶
Atan returns the arctangent, in radians, of x.
Range:
Input: all real numbers Output: -pi/2 <= Atan(x) <= pi/2
Special cases:
Atan(NaN) = NaN Atan(±Inf) = ±x * pi/2
func (Context) Atan2 ¶
Atan2 calculates arctan of y/x and uses the signs of y and x to determine the valid quadrant
Range:
y input: all real numbers x input: all real numbers Output: -pi < Atan2(y, x) <= pi
Special cases:
Atan2(NaN, NaN) = NaN Atan2(y, NaN) = NaN Atan2(NaN, x) = NaN Atan2(±0, x >=0) = ±0 Atan2(±0, x <= -0) = ±pi Atan2(y > 0, 0) = +pi/2 Atan2(y < 0, 0) = -pi/2 Atan2(±Inf, +Inf) = ±pi/4 Atan2(±Inf, -Inf) = ±3pi/4 Atan2(y, +Inf) = 0 Atan2(y > 0, -Inf) = +pi Atan2(y < 0, -Inf) = -pi Atan2(±Inf, x) = ±pi/2 Atan2(y, x > 0) = Atan(y/x) Atan2(y >= 0, x < 0) = Atan(y/x) + pi Atan2(y < 0, x < 0) = Atan(y/x) - pi
func (Context) Ceil ¶
Ceil sets z to the least integer value greater than or equal to x and returns z.
func (Context) Cos ¶
Cos returns the cosine, in radians, of x.
Range:
Input: all real numbers Output: -1 <= Cos(x) <= 1
Special cases:
Cos(NaN) = NaN Cos(±Inf) = NaN
func (Context) Floor ¶
Floor sets z to the greatest integer value less than or equal to x and returns z.
func (Context) Lentz ¶
Lentz sets z to the result of the continued fraction provided by the Generator and returns z.
The continued fraction should be represented as such:
a1 f(x) = b0 + -------------------- a2 b1 + --------------- a3 b2 + ---------- a4 b3 + ----- ...
Or, equivalently:
a1 a2 a3 f(x) = b0 + ---- ---- ---- b1 + b2 + b3 + ···
If terms need to be subtracted, the a_N terms should be negative. To compute a continued fraction without b_0, divide the result by a_1.
If the first call to the Generator's Next method returns false, the result of Lentz is undefined.
Note: the accuracy of the result may be affected by the precision of intermediate results. If larger precision is desired, it may be necessary for the Generator to implement the Lentzer interface and set a higher precision for f, Δ, C, and D.
Example (Phi) ¶
This example demonstrates using Lentz by calculating the golden ratio, φ.
package main import ( "fmt" "math" ) type phiGenerator struct { ctx Context } func (p phiGenerator) Context() Context { return p.ctx } func (phiGenerator) Next() bool { return true } func (phiGenerator) Term() Term { return Term{A: New(1, 0), B: New(1, 0)} } func (p phiGenerator) Lentz() (f, Δ, C, D, eps *Big) { // Add a little extra precision to C and D so we get an "exact" result after // rounding. f = WithContext(p.ctx) Δ = WithContext(p.ctx) C = WithContext(p.ctx) D = WithContext(p.ctx) scale := p.ctx.Precision if scale == 0 { scale = DefaultPrecision } eps = New(1, scale) return f, Δ, C, D, eps } // Phi sets z to the golden ratio, φ, and returns z. func Phi(ctx Context, z *Big) *Big { ctx.Precision++ ctx.Wallis(z, phiGenerator{ctx: ctx}) ctx.Precision-- return ctx.Round(z) } // This example demonstrates using Lentz by calculating the // golden ratio, φ. func main() { ctx := Context64 var z Big Phi(ctx, &z) p := (1 + math.Sqrt(5)) / 2 fmt.Printf(` Go : %g Decimal: %s`, p, &z) }
Output: Go : 1.618033988749895 Decimal: 1.618033988749895
Example (Tan) ¶
package main import ( "fmt" ) type tanGenerator struct { ctx Context k uint64 a *Big b *Big } func (t tanGenerator) Next() bool { return true } func (t *tanGenerator) Term() Term { t.k += 2 return Term{A: t.a, B: t.b.SetUint64(t.k)} } func (t *tanGenerator) Context() Context { return t.ctx } // Tan sets z to the tangent of the radian argument x. func Tan(ctx Context, z, x *Big) *Big { // Handle special cases like 0, Inf, and NaN. // In the continued fraction // // z z^2 z^2 z^2 // tan(z) = ----- ----- ----- ----- // 1 - 3 - 5 - 7 - ··· // // the terms are subtracted, so we need to negate "A" work := ctx if work.Precision == 0 { work.Precision = DefaultPrecision } work.Precision++ x0 := work.Mul(new(Big), x, x) x0.Neg(x0) g := &tanGenerator{ ctx: ctx, k: 1<<64 - 1, a: x0, b: new(Big), } // Since our fraction doesn't have a leading (b0), we need to // divide our result by a1. tan := work.Quo(z, x, work.Lentz(z, g)) return ctx.Set(z, tan) } func main() { var z Big ctx := Context{Precision: 17} x := New(42, 0) fmt.Printf("tan(42) = %s\n", Tan(ctx, &z, x).Round(16)) }
Output: tan(42) = 2.291387992437486
func (Context) Neg ¶
Neg sets z to -x and returns z.
If x is positive infinity, z will be set to negative infinity and vice versa. If x == 0, z will be set to zero. It is an error if x is a NaN value
func (Context) NextMinus ¶
NextMinus sets z to the smallest representable number that's smaller than x and returns z.
If x is negative infinity the result will be negative infinity. If the result is zero its sign will be negative and its scale will be MinScale.
func (Context) NextPlus ¶
NextPlus sets z to the largest representable number that's larger than x and returns z.
If x is positive infinity the result will be positive infinity. If the result is zero it will be positive and its scale will be MaxScale.
func (Context) Quantize ¶
Quantize sets z to the number equal in value and sign to z with the scale, n.
In order to perform truncation, set the Context's RoundingMode to ToZero.
func (Context) QuoInt ¶
QuoInt sets z to x / y with the remainder truncated. See QuoRem for more details.
func (Context) QuoRem ¶
QuoRem sets z to the quotient x / y and r to the remainder x % y, such that x = z * y + r, and returns the pair (z, r).
func (Context) Round ¶
Round rounds z down to the Context's precision and returns z.
For a finite z, result of Round will always be within the interval [⌊10**p⌋, z] where p = the precision of z. The result is undefined if z is not finite.
func (Context) RoundToInt ¶
RoundToInt rounds z down to an integral value.
func (Context) SetString ¶
SetString sets z to the value of s, returning z and a bool indicating success.
See Big.SetString for valid formats.
func (Context) Sin ¶
Sin returns the sine, in radians, of x.
Range:
Input: all real numbers Output: -1 <= Sin(x) <= 1
Special cases:
Sin(NaN) = NaN Sin(Inf) = NaN
func (Context) Tan ¶
Tan returns the tangent, in radians, of x.
Range:
Input: -pi/2 <= x <= pi/2 Output: all real numbers
Special cases:
Tan(NaN) = NaN Tan(±Inf) = NaN
func (Context) Wallis ¶
Wallis sets z to the result of the continued fraction provided by the Generator and returns z.
The fraction is evaluated in a top-down manner, using the recurrence algorithm discovered by John Wallis. For more information on continued fraction representations, see the Lentz function.
type Contexter ¶
type Contexter interface {
Context() Context
}
Contexter allows Generators to provide a different Context than z's. It's intended to be analogous to the relationship between, for example, Context.Mul and Big.Mul.
type ErrNaN ¶
type ErrNaN struct {
Msg string
}
An ErrNaN is used when a decimal operation would lead to a NaN under IEEE-754 rules. An ErrNaN implements the error interface.
type Generator ¶
type Generator interface { // Next returns true if there are future terms. Every call to Term—even the // first—must be preceded by a call to Next. In general, Generators should // always return true unless an exceptional condition occurs. Next() bool // Term returns the next term in the fraction. The caller must not modify // any of the Term's fields. Term() Term }
Generator represents a continued fraction.
type Lentzer ¶
type Lentzer interface { // Lentz provides the backing storage for a Generator passed to the Lentz // function. // // In Contexter isn't implemented, f, Δ, C, and D should have large enough // precision to provide a correct result, (See note for the Lentz function.) // // eps should be a sufficiently small decimal, likely 1e-15 or smaller. // // For more information, refer to "Numerical Recipes in C: The Art of // Scientific Computing" (ISBN 0-521-43105-5), pg 171. Lentz() (f, Δ, C, D, eps *Big) }
Lentzer, if implemented, allows Generators to provide their own backing storage for the Lentz function.
type OperatingMode ¶
type OperatingMode uint8
OperatingMode dictates how the decimal approaches specific non-numeric operations like conversions to strings and panicking on NaNs.
const ( // GDA strictly adheres to the General Decimal Arithmetic Specification // Version 1.70. In particular: // // - at does not panic // - all arithmetic operations will be rounded down to the proper precision // if necessary // - it utilizes traps to set both Context.Err and Context.Conditions // - its string forms of qNaN, sNaN, +Inf, and -Inf are "NaN", "sNaN", // "Infinity", and "-Infinity", respectively // GDA OperatingMode = iota // Go adheres to typical Go idioms. In particular: // // - it panics on NaN values // - has lossless (i.e., without rounding) addition, subtraction, and // multiplication // - traps are ignored; it does not set Context.Err or Context.Conditions // - its string forms of qNaN, sNaN, +Inf, and -Inf are "NaN", "NaN", // "+Inf", and "-Inf", respectively // Go )
func (OperatingMode) String ¶
func (i OperatingMode) String() string
type RoundingMode ¶
type RoundingMode uint8
RoundingMode determines how a decimal will be rounded.
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 ToNearestTowardZero // no IEEE 754-2008 equivalent )
The following rounding modes are supported.
func (RoundingMode) String ¶
func (i RoundingMode) String() string
type SplitFunc ¶
SplitFunc returns the intermediate value for a given n. The returned decimal must not be modified by the caller and may only be valid until the next invocation of said function. This allows the implementation to conserve memory usage.
type Term ¶
type Term struct {
A, B *Big
}
Term is a specific term in a continued fraction. A and B correspond with the a and b variables of the typical representation of a continued fraction. An example can be seen in the book, “Numerical Recipes in C: The Art of Scientific Computing” (ISBN 0-521-43105-5) in figure 5.2.1 on page 169.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
fuzz
|
|
internal
|
|
arith
Package arith provides performance-sensitive arithmetic operations.
|
Package arith provides performance-sensitive arithmetic operations. |
c
Package c provides internal constants.
|
Package c provides internal constants. |
Package math implements various useful mathematical functions and constants.
|
Package math implements various useful mathematical functions and constants. |
debug
Package debug provides simple routines for debugging continued fractions.
|
Package debug provides simple routines for debugging continued fractions. |
Package misc contains miscellaneous decimal routes.
|
Package misc contains miscellaneous decimal routes. |
Package sql provides the ability to use Big decimals with SQL databases.
|
Package sql provides the ability to use Big decimals with SQL databases. |
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" |