apd

package module
v3.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2023 License: Apache-2.0 Imports: 10 Imported by: 107

README

apd

apd is an arbitrary-precision decimal package for Go.

apd implements much of the decimal specification from the General Decimal Arithmetic description. This is the same specification implemented by python’s decimal module and GCC’s decimal extension.

Features

  • Panic-free operation. The math/big types don’t return errors, and instead panic under some conditions that are documented. This requires users to validate the inputs before using them. Meanwhile, we’d like our decimal operations to have more failure modes and more input requirements than the math/big types, so using that API would be difficult. apd instead returns errors when needed.
  • Support for standard functions. sqrt, ln, pow, etc.
  • Accurate and configurable precision. Operations will use enough internal precision to produce a correct result at the requested precision. Precision is set by a "context" structure that accompanies the function arguments, as discussed in the next section.
  • Good performance. Operations will either be fast enough or will produce an error if they will be slow. This prevents edge-case operations from consuming lots of CPU or memory.
  • Condition flags and traps. All operations will report whether their result is exact, is rounded, is over- or under-flowed, is subnormal, or is some other condition. apd supports traps which will trigger an error on any of these conditions. This makes it possible to guarantee exactness in computations, if needed.

apd has three main types.

The first is BigInt which is a wrapper around big.Int that exposes an identical API while reducing memory allocations. BigInt does so by using an inline array to back the big.Int's variable-length value when the integer's absolute value is sufficiently small. BigInt also contains fast-paths that allow it to perform basic arithmetic directly on this inline array, only falling back to big.Int when the arithmetic gets complex or takes place on large values.

The second is Decimal which holds the values of decimals. It is simple and uses a BigInt with an exponent to describe values. Most operations on Decimals can’t produce errors as they work directly on the underlying big.Int. Notably, however, there are no arithmetic operations on Decimals.

The third main type is Context, which is where all arithmetic operations are defined. A Context describes the precision, range, and some other restrictions during operations. These operations can all produce failures, and so return errors.

Context operations, in addition to errors, return a Condition, which is a bitfield of flags that occurred during an operation. These include overflow, underflow, inexact, rounded, and others. The Traps field of a Context can be set which will produce an error if the corresponding flag occurs. An example of this is given below.

See the examples for some operations that were previously difficult to perform in Go.

Documentation

https://pkg.go.dev/github.com/cockroachdb/apd/v3?tab=doc

Documentation

Overview

Package apd implements arbitrary-precision decimals.

apd implements much of the decimal specification from the General Decimal Arithmetic (http://speleotrove.com/decimal/) description, which is refered to here as GDA. This is the same specification implemented by pythons decimal module (https://docs.python.org/2/library/decimal.html) and GCCs decimal extension.

Features

Panic-free operation. The math/big types don’t return errors, and instead panic under some conditions that are documented. This requires users to validate the inputs before using them. Meanwhile, we’d like our decimal operations to have more failure modes and more input requirements than the math/big types, so using that API would be difficult. apd instead returns errors when needed.

Support for standard functions. sqrt, ln, pow, etc.

Accurate and configurable precision. Operations will use enough internal precision to produce a correct result at the requested precision. Precision is set by a "context" structure that accompanies the function arguments, as discussed in the next section.

Good performance. Operations will either be fast enough or will produce an error if they will be slow. This prevents edge-case operations from consuming lots of CPU or memory.

Condition flags and traps. All operations will report whether their result is exact, is rounded, is over- or under-flowed, is subnormal (https://en.wikipedia.org/wiki/Denormal_number), or is some other condition. apd supports traps which will trigger an error on any of these conditions. This makes it possible to guarantee exactness in computations, if needed.

SQL scan and value methods are implemented. This allows the use of Decimals as placeholder parameters and row result Scan destinations.

Usage

apd has two main types. The first is Decimal which holds the values of decimals. It is simple and uses a big.Int with an exponent to describe values. Most operations on Decimals can’t produce errors as they work directly on the underlying big.Int. Notably, however, there are no arithmetic operations on Decimals.

The second main type is Context, which is where all arithmetic operations are defined. A Context describes the precision, range, and some other restrictions during operations. These operations can all produce failures, and so return errors.

Context operations, in addition to errors, return a Condition, which is a bitfield of flags that occurred during an operation. These include overflow, underflow, inexact, rounded, and others. The Traps field of a Context can be set which will produce an error if the corresponding flag occurs. An example of this is given below.

Index

Examples

Constants

View Source
const (

	// MaxExponent is the highest exponent supported. Exponents near this range will
	// perform very slowly (many seconds per operation).
	MaxExponent = 100000
	// MinExponent is the lowest exponent supported with the same limitations as
	// MaxExponent.
	MinExponent = -MaxExponent
)
View Source
const (
	// DefaultTraps is the default trap set used by BaseContext.
	DefaultTraps = SystemOverflow |
		SystemUnderflow |
		Overflow |
		Underflow |
		Subnormal |
		DivisionUndefined |
		DivisionByZero |
		DivisionImpossible |
		InvalidOperation
)

Variables

View Source
var BaseContext = Context{

	Precision: 0,

	MaxExponent: MaxExponent,
	MinExponent: MinExponent,

	Traps: DefaultTraps,
}

BaseContext is a useful default Context. Should not be mutated.

Functions

func NewFromString

func NewFromString(s string) (*Decimal, Condition, error)

NewFromString creates a new decimal from s. It has no restrictions on exponents or precision.

func NumDigits

func NumDigits(b *BigInt) int64

NumDigits returns the number of decimal digits of b.

Types

type BigInt

type BigInt struct {
	// contains filtered or unexported fields
}

BigInt is a wrapper around big.Int. It minimizes memory allocation by using an inline array to back the big.Int's variable-length "nat" slice when the integer's value is sufficiently small. The zero value is ready to use.

func NewBigInt

func NewBigInt(x int64) *BigInt

NewBigInt allocates and returns a new BigInt set to x.

NOTE: BigInt jumps through hoops to avoid escaping to the heap. As such, most users of BigInt should not need this function. They should instead declare a zero-valued BigInt directly on the stack and interact with references to this stack-allocated value. Recall that the zero-valued BigInt is ready to use.

func (*BigInt) Abs

func (z *BigInt) Abs(x *BigInt) *BigInt

Abs calls (big.Int).Abs.

func (*BigInt) Add

func (z *BigInt) Add(x, y *BigInt) *BigInt

Add calls (big.Int).Add.

func (*BigInt) And

func (z *BigInt) And(x, y *BigInt) *BigInt

And calls (big.Int).And.

func (*BigInt) AndNot

func (z *BigInt) AndNot(x, y *BigInt) *BigInt

AndNot calls (big.Int).AndNot.

func (*BigInt) Append

func (z *BigInt) Append(buf []byte, base int) []byte

Append calls (big.Int).Append.

func (*BigInt) Binomial

func (z *BigInt) Binomial(n, k int64) *BigInt

Binomial calls (big.Int).Binomial.

func (*BigInt) Bit

func (z *BigInt) Bit(i int) uint

Bit calls (big.Int).Bit.

func (*BigInt) BitLen

func (z *BigInt) BitLen() int

BitLen calls (big.Int).BitLen.

func (*BigInt) Bits

func (z *BigInt) Bits() []big.Word

Bits calls (big.Int).Bits.

func (*BigInt) Bytes

func (z *BigInt) Bytes() []byte

Bytes calls (big.Int).Bytes.

func (*BigInt) Cmp

func (z *BigInt) Cmp(y *BigInt) (r int)

Cmp calls (big.Int).Cmp.

func (*BigInt) CmpAbs

func (z *BigInt) CmpAbs(y *BigInt) (r int)

CmpAbs calls (big.Int).CmpAbs.

func (*BigInt) Div

func (z *BigInt) Div(x, y *BigInt) *BigInt

Div calls (big.Int).Div.

func (*BigInt) DivMod

func (z *BigInt) DivMod(x, y, m *BigInt) (*BigInt, *BigInt)

DivMod calls (big.Int).DivMod.

func (*BigInt) Exp

func (z *BigInt) Exp(x, y, m *BigInt) *BigInt

Exp calls (big.Int).Exp.

func (*BigInt) FillBytes

func (z *BigInt) FillBytes(buf []byte) []byte

FillBytes calls (big.Int).FillBytes.

func (*BigInt) Format

func (z *BigInt) Format(s fmt.State, ch rune)

Format calls (big.Int).Format.

func (*BigInt) GCD

func (z *BigInt) GCD(x, y, a, b *BigInt) *BigInt

GCD calls (big.Int).GCD.

func (*BigInt) GobDecode

func (z *BigInt) GobDecode(buf []byte) error

GobDecode calls (big.Int).GobDecode.

func (*BigInt) GobEncode

func (z *BigInt) GobEncode() ([]byte, error)

GobEncode calls (big.Int).GobEncode.

func (*BigInt) Int64

func (z *BigInt) Int64() int64

Int64 calls (big.Int).Int64.

func (*BigInt) IsInt64

func (z *BigInt) IsInt64() bool

IsInt64 calls (big.Int).IsInt64.

func (*BigInt) IsUint64

func (z *BigInt) IsUint64() bool

IsUint64 calls (big.Int).IsUint64.

func (*BigInt) Lsh

func (z *BigInt) Lsh(x *BigInt, n uint) *BigInt

Lsh calls (big.Int).Lsh.

func (*BigInt) MarshalJSON

func (z *BigInt) MarshalJSON() ([]byte, error)

MarshalJSON calls (big.Int).MarshalJSON.

func (*BigInt) MarshalText

func (z *BigInt) MarshalText() (text []byte, err error)

MarshalText calls (big.Int).MarshalText.

func (*BigInt) MathBigInt

func (z *BigInt) MathBigInt() *big.Int

MathBigInt returns the math/big.Int representation of z.

func (*BigInt) Mod

func (z *BigInt) Mod(x, y *BigInt) *BigInt

Mod calls (big.Int).Mod.

func (*BigInt) ModInverse

func (z *BigInt) ModInverse(g, n *BigInt) *BigInt

ModInverse calls (big.Int).ModInverse.

func (*BigInt) ModSqrt

func (z *BigInt) ModSqrt(x, p *BigInt) *BigInt

ModSqrt calls (big.Int).ModSqrt.

func (*BigInt) Mul

func (z *BigInt) Mul(x, y *BigInt) *BigInt

Mul calls (big.Int).Mul.

func (*BigInt) MulRange

func (z *BigInt) MulRange(x, y int64) *BigInt

MulRange calls (big.Int).MulRange.

func (*BigInt) Neg

func (z *BigInt) Neg(x *BigInt) *BigInt

Neg calls (big.Int).Neg.

func (*BigInt) Not

func (z *BigInt) Not(x *BigInt) *BigInt

Not calls (big.Int).Not.

func (*BigInt) Or

func (z *BigInt) Or(x, y *BigInt) *BigInt

Or calls (big.Int).Or.

func (*BigInt) ProbablyPrime

func (z *BigInt) ProbablyPrime(n int) bool

ProbablyPrime calls (big.Int).ProbablyPrime.

func (*BigInt) Quo

func (z *BigInt) Quo(x, y *BigInt) *BigInt

Quo calls (big.Int).Quo.

func (*BigInt) QuoRem

func (z *BigInt) QuoRem(x, y, r *BigInt) (*BigInt, *BigInt)

QuoRem calls (big.Int).QuoRem.

func (*BigInt) Rand

func (z *BigInt) Rand(rnd *rand.Rand, n *BigInt) *BigInt

Rand calls (big.Int).Rand.

func (*BigInt) Rem

func (z *BigInt) Rem(x, y *BigInt) *BigInt

Rem calls (big.Int).Rem.

func (*BigInt) Rsh

func (z *BigInt) Rsh(x *BigInt, n uint) *BigInt

Rsh calls (big.Int).Rsh.

func (*BigInt) Scan

func (z *BigInt) Scan(s fmt.ScanState, ch rune) error

Scan calls (big.Int).Scan.

func (*BigInt) Set

func (z *BigInt) Set(x *BigInt) *BigInt

Set calls (big.Int).Set.

func (*BigInt) SetBit

func (z *BigInt) SetBit(x *BigInt, i int, b uint) *BigInt

SetBit calls (big.Int).SetBit.

func (*BigInt) SetBits

func (z *BigInt) SetBits(abs []big.Word) *BigInt

SetBits calls (big.Int).SetBits.

func (*BigInt) SetBytes

func (z *BigInt) SetBytes(buf []byte) *BigInt

SetBytes calls (big.Int).SetBytes.

func (*BigInt) SetInt64

func (z *BigInt) SetInt64(x int64) *BigInt

SetInt64 calls (big.Int).SetInt64.

func (*BigInt) SetMathBigInt

func (z *BigInt) SetMathBigInt(x *big.Int) *BigInt

SetMathBigInt sets z to x and returns z.

func (*BigInt) SetString

func (z *BigInt) SetString(s string, base int) (*BigInt, bool)

SetString calls (big.Int).SetString.

func (*BigInt) SetUint64

func (z *BigInt) SetUint64(x uint64) *BigInt

SetUint64 calls (big.Int).SetUint64.

func (*BigInt) Sign

func (z *BigInt) Sign() int

Sign calls (big.Int).Sign.

func (*BigInt) Size

func (z *BigInt) Size() uintptr

Size returns the total memory footprint of z in bytes.

func (*BigInt) Sqrt

func (z *BigInt) Sqrt(x *BigInt) *BigInt

Sqrt calls (big.Int).Sqrt.

func (*BigInt) String

func (z *BigInt) String() string

String calls (big.Int).String.

func (*BigInt) Sub

func (z *BigInt) Sub(x, y *BigInt) *BigInt

Sub calls (big.Int).Sub.

func (*BigInt) Text

func (z *BigInt) Text(base int) string

Text calls (big.Int).Text.

func (*BigInt) TrailingZeroBits

func (z *BigInt) TrailingZeroBits() uint

TrailingZeroBits calls (big.Int).TrailingZeroBits.

func (*BigInt) Uint64

func (z *BigInt) Uint64() uint64

Uint64 calls (big.Int).Uint64.

func (*BigInt) UnmarshalJSON

func (z *BigInt) UnmarshalJSON(text []byte) error

UnmarshalJSON calls (big.Int).UnmarshalJSON.

func (*BigInt) UnmarshalText

func (z *BigInt) UnmarshalText(text []byte) error

UnmarshalText calls (big.Int).UnmarshalText.

func (*BigInt) Xor

func (z *BigInt) Xor(x, y *BigInt) *BigInt

Xor calls (big.Int).Xor.

type Condition

type Condition uint32

Condition holds condition flags.

const (
	// SystemOverflow is raised when an exponent is greater than MaxExponent.
	SystemOverflow Condition = 1 << iota
	// SystemUnderflow is raised when an exponent is less than MinExponent.
	SystemUnderflow
	// Overflow is raised when the exponent of a result is too large to be
	// represented.
	Overflow
	// Underflow is raised when a result is both subnormal and inexact.
	Underflow
	// Inexact is raised when a result is not exact (one or more non-zero
	// coefficient digits were discarded during rounding).
	Inexact
	// Subnormal is raised when a result is subnormal (its adjusted exponent is
	// less than Emin), before any rounding.
	Subnormal
	// Rounded is raised when a result has been rounded (that is, some zero or
	// non-zero coefficient digits were discarded).
	Rounded
	// DivisionUndefined is raised when both division operands are 0.
	DivisionUndefined
	// DivisionByZero is raised when a non-zero dividend is divided by zero.
	DivisionByZero
	// DivisionImpossible is raised when integer division cannot be exactly
	// represented with the given precision.
	DivisionImpossible
	// InvalidOperation is raised when a result would be undefined or impossible.
	InvalidOperation
	// Clamped is raised when the exponent of a result has been altered or
	// constrained in order to fit the constraints of the Decimal representation.
	Clamped
)

func (Condition) Any

func (r Condition) Any() bool

Any returns true if any flag is true.

func (Condition) Clamped

func (r Condition) Clamped() bool

Clamped returns true if the Clamped flag is set.

func (Condition) DivisionByZero

func (r Condition) DivisionByZero() bool

DivisionByZero returns true if the DivisionByZero flag is set.

func (Condition) DivisionImpossible

func (r Condition) DivisionImpossible() bool

DivisionImpossible returns true if the DivisionImpossible flag is set.

func (Condition) DivisionUndefined

func (r Condition) DivisionUndefined() bool

DivisionUndefined returns true if the DivisionUndefined flag is set.

func (Condition) GoError

func (r Condition) GoError(traps Condition) (Condition, error)

GoError converts r to an error based on the given traps and returns r. Traps are the conditions which will trigger an error result if the corresponding Flag condition occurred.

func (Condition) Inexact

func (r Condition) Inexact() bool

Inexact returns true if the Inexact flag is set.

func (Condition) InvalidOperation

func (r Condition) InvalidOperation() bool

InvalidOperation returns true if the InvalidOperation flag is set.

func (Condition) Overflow

func (r Condition) Overflow() bool

Overflow returns true if the Overflow flag is set.

func (Condition) Rounded

func (r Condition) Rounded() bool

Rounded returns true if the Rounded flag is set.

func (Condition) String

func (r Condition) String() string

func (Condition) Subnormal

func (r Condition) Subnormal() bool

Subnormal returns true if the Subnormal flag is set.

func (Condition) SystemOverflow

func (r Condition) SystemOverflow() bool

SystemOverflow returns true if the SystemOverflow flag is set.

func (Condition) SystemUnderflow

func (r Condition) SystemUnderflow() bool

SystemUnderflow returns true if the SystemUnderflow flag is set.

func (Condition) Underflow

func (r Condition) Underflow() bool

Underflow returns true if the Underflow flag is set.

type Context

type Context struct {
	// Precision is the number of places to round during rounding; this is
	// effectively the total number of digits (before and after the decimal
	// point).
	Precision uint32
	// MaxExponent specifies the largest effective exponent. The
	// effective exponent is the value of the Decimal in scientific notation. That
	// is, for 10e2, the effective exponent is 3 (1.0e3). Zero (0) is not a special
	// value; it does not disable this check.
	MaxExponent int32
	// MinExponent is similar to MaxExponent, but for the smallest effective
	// exponent.
	MinExponent int32
	// Traps are the conditions which will trigger an error result if the
	// corresponding Flag condition occurred.
	Traps Condition
	// Rounding specifies the Rounder to use during rounding. RoundHalfUp is used if
	// empty or not present in Roundings.
	Rounding Rounder
}

Context maintains options for Decimal operations. It can safely be used concurrently, but not modified concurrently. Arguments for any method can safely be used as both result and operand.

Example (Inexact)

ExampleInexact demonstrates how to detect inexact operations.

d := apd.New(27, 0)
three := apd.New(3, 0)
c := apd.BaseContext.WithPrecision(5)
for {
	res, err := c.Quo(d, d, three)
	fmt.Printf("d: %7s, inexact: %5v, err: %v\n", d, res.Inexact(), err)
	if err != nil {
		return
	}
	if res.Inexact() {
		return
	}
}
Output:

d:  9.0000, inexact: false, err: <nil>
d:  3.0000, inexact: false, err: <nil>
d:  1.0000, inexact: false, err: <nil>
d: 0.33333, inexact:  true, err: <nil>
Example (Overflow)

ExampleOverflow demonstrates how to detect or error on overflow.

// Create a context that will overflow at 1e3.
c := apd.Context{
	MaxExponent: 2,
	Traps:       apd.Overflow,
}
one := apd.New(1, 0)
d := apd.New(997, 0)
for {
	res, err := c.Add(d, d, one)
	fmt.Printf("d: %8s, overflow: %5v, err: %v\n", d, res.Overflow(), err)
	if err != nil {
		return
	}
}
Output:

d:      998, overflow: false, err: <nil>
d:      999, overflow: false, err: <nil>
d: Infinity, overflow:  true, err: overflow

func (*Context) Abs

func (c *Context) Abs(d, x *Decimal) (Condition, error)

Abs sets d to |x| (the absolute value of x).

func (*Context) Add

func (c *Context) Add(d, x, y *Decimal) (Condition, error)

Add sets d to the sum x+y.

func (*Context) Cbrt

func (c *Context) Cbrt(d, x *Decimal) (Condition, error)

Cbrt sets d to the cube root of x.

func (*Context) Ceil

func (c *Context) Ceil(d, x *Decimal) (Condition, error)

Ceil sets d to the smallest integer >= x.

func (*Context) Cmp

func (c *Context) Cmp(d, x, y *Decimal) (Condition, error)

Cmp compares x and y and sets d to:

-1 if x <  y
 0 if x == y
+1 if x >  y

This comparison respects the normal rules of special values (like NaN), and does not compare them.

func (*Context) Exp

func (c *Context) Exp(d, x *Decimal) (Condition, error)

Exp sets d = e**x.

func (*Context) Floor

func (c *Context) Floor(d, x *Decimal) (Condition, error)

Floor sets d to the largest integer <= x.

func (*Context) Ln

func (c *Context) Ln(d, x *Decimal) (Condition, error)

Ln sets d to the natural log of x.

func (*Context) Log10

func (c *Context) Log10(d, x *Decimal) (Condition, error)

Log10 sets d to the base 10 log of x.

func (*Context) Mul

func (c *Context) Mul(d, x, y *Decimal) (Condition, error)

Mul sets d to the product x*y.

func (*Context) Neg

func (c *Context) Neg(d, x *Decimal) (Condition, error)

Neg sets d to -x.

func (*Context) NewFromString

func (c *Context) NewFromString(s string) (*Decimal, Condition, error)

NewFromString creates a new decimal from s. The returned Decimal has its exponents restricted by the context and its value rounded if it contains more digits than the context's precision.

func (*Context) Pow

func (c *Context) Pow(d, x, y *Decimal) (Condition, error)

Pow sets d = x**y.

func (*Context) Quantize

func (c *Context) Quantize(d, x *Decimal, exp int32) (Condition, error)

Quantize adjusts and rounds x as necessary so it is represented with exponent exp and stores the result in d.

Example
input, _, _ := apd.NewFromString("123.45")
output := new(apd.Decimal)
c := apd.BaseContext.WithPrecision(10)
for i := int32(-3); i <= 3; i++ {
	res, _ := c.Quantize(output, input, i)
	fmt.Printf("%2v: %s", i, output)
	if res != 0 {
		fmt.Printf(" (%s)", res)
	}
	fmt.Println()
}
Output:

-3: 123.450
-2: 123.45
-1: 123.5 (inexact, rounded)
 0: 123 (inexact, rounded)
 1: 1.2E+2 (inexact, rounded)
 2: 1E+2 (inexact, rounded)
 3: 0E+3 (inexact, rounded)

func (*Context) Quo

func (c *Context) Quo(d, x, y *Decimal) (Condition, error)

Quo sets d to the quotient x/y for y != 0. c.Precision must be > 0. If an exact division is required, use a context with high precision and verify it was exact by checking the Inexact flag on the return Condition.

func (*Context) QuoInteger

func (c *Context) QuoInteger(d, x, y *Decimal) (Condition, error)

QuoInteger sets d to the integer part of the quotient x/y. If the result cannot fit in d.Precision digits, an error is returned.

func (*Context) Reduce

func (c *Context) Reduce(d, x *Decimal) (int, Condition, error)

Reduce sets d to x with all trailing zeros removed and returns the number of zeros removed.

func (*Context) Rem

func (c *Context) Rem(d, x, y *Decimal) (Condition, error)

Rem sets d to the remainder part of the quotient x/y. If the integer part cannot fit in d.Precision digits, an error is returned.

func (*Context) Round

func (c *Context) Round(d, x *Decimal) (Condition, error)

Round sets d to rounded x, rounded to the precision specified by c. If c has zero precision, no rounding will occur. If c has no Rounding specified, RoundHalfUp is used.

func (*Context) RoundToIntegralExact

func (c *Context) RoundToIntegralExact(d, x *Decimal) (Condition, error)

RoundToIntegralExact sets d to integral value of x.

Example

ExampleRoundToIntegralExact demonstrates how to use RoundToIntegralExact to check if a number is an integer or not. Note the variations between integer (which allows zeros after the decimal point) and strict (which does not). See the documentation on Inexact and Rounded.

inputs := []string{
	"123.4",
	"123.0",
	"123",
	"12E1",
	"120E-1",
	"120E-2",
}
for _, input := range inputs {
	d, _, _ := apd.NewFromString(input)
	res, _ := apd.BaseContext.RoundToIntegralExact(d, d)
	integer := !res.Inexact()
	strict := !res.Rounded()
	fmt.Printf("input: % 6s, output: %3s, integer: %5t, strict: %5t, res:", input, d, integer, strict)
	if res != 0 {
		fmt.Printf(" %s", res)
	}
	fmt.Println()
}
Output:

input:  123.4, output: 123, integer: false, strict: false, res: inexact, rounded
input:  123.0, output: 123, integer:  true, strict: false, res: rounded
input:    123, output: 123, integer:  true, strict:  true, res:
input:   12E1, output: 120, integer:  true, strict:  true, res:
input: 120E-1, output:  12, integer:  true, strict: false, res: rounded
input: 120E-2, output:   1, integer: false, strict: false, res: inexact, rounded

func (*Context) RoundToIntegralValue

func (c *Context) RoundToIntegralValue(d, x *Decimal) (Condition, error)

RoundToIntegralValue sets d to integral value of x. Inexact and Rounded flags are ignored and removed.

func (*Context) SetString

func (c *Context) SetString(d *Decimal, s string) (*Decimal, Condition, error)

SetString sets d to s and returns d. The returned Decimal has its exponents restricted by the context and its value rounded if it contains more digits than the context's precision.

func (*Context) Sqrt

func (c *Context) Sqrt(d, x *Decimal) (Condition, error)

Sqrt sets d to the square root of x. Sqrt uses the Babylonian method for computing the square root, which uses O(log p) steps for p digits of precision.

func (*Context) Sub

func (c *Context) Sub(d, x, y *Decimal) (Condition, error)

Sub sets d to the difference x-y.

func (*Context) WithPrecision

func (c *Context) WithPrecision(p uint32) *Context

WithPrecision returns a copy of c but with the specified precision.

type Decimal

type Decimal struct {
	Form     Form
	Negative bool
	Exponent int32
	Coeff    BigInt
}

Decimal is an arbitrary-precision decimal. Its value is:

Negative × Coeff × 10**Exponent

Coeff must be positive. If it is negative results may be incorrect and apd may panic.

func New

func New(coeff int64, exponent int32) *Decimal

New creates a new decimal with the given coefficient and exponent.

func NewWithBigInt

func NewWithBigInt(coeff *BigInt, exponent int32) *Decimal

NewWithBigInt creates a new decimal with the given coefficient and exponent.

func (*Decimal) Abs

func (d *Decimal) Abs(x *Decimal) *Decimal

Abs sets d to |x| and returns d.

func (*Decimal) Append

func (d *Decimal) Append(buf []byte, fmtString byte) []byte

Append appends to buf the string form of the decimal number d, as generated by d.Text, and returns the extended buffer.

func (*Decimal) Cmp

func (d *Decimal) Cmp(x *Decimal) int

Cmp compares d and x and returns:

-1 if d <  x
 0 if d == x
+1 if d >  x
undefined if d or x are NaN

func (*Decimal) CmpTotal

func (d *Decimal) CmpTotal(x *Decimal) int

CmpTotal compares d and x using their abstract representation rather than their numerical value. A total ordering is defined for all possible abstract representations, as described below. If the first operand is lower in the total order than the second operand then the result is -1, if the operands have the same abstract representation then the result is 0, and if the first operand is higher in the total order than the second operand then the result is 1.

Numbers (representations which are not NaNs) are ordered such that a larger numerical value is higher in the ordering. If two representations have the same numerical value then the exponent is taken into account; larger (more positive) exponents are higher in the ordering.

For example, the following values are ordered from lowest to highest. Note the difference in ordering between 1.2300 and 1.23.

-NaN
-NaNSignaling
-Infinity
-127
-1.00
-1
-0.000
-0
0
1.2300
1.23
1E+9
Infinity
NaNSignaling
NaN

func (*Decimal) Compose

func (d *Decimal) Compose(form byte, negative bool, coefficient []byte, exponent int32) error

Compose sets the internal decimal value from parts. If the value cannot be represented then an error should be returned.

func (*Decimal) Decompose

func (d *Decimal) Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)

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 (*Decimal) Float64

func (d *Decimal) Float64() (float64, error)

Float64 returns the float64 representation of x. This conversion may lose data (see strconv.ParseFloat for caveats).

func (*Decimal) Format

func (d *Decimal) Format(s fmt.State, format rune)

Format implements fmt.Formatter. It accepts many of the regular formats for floating-point numbers ('e', 'E', 'f', 'F', 'g', 'G') as well as 's' and 'v', which are handled like 'G'. Format also supports the output field width, as well as the format flags '+' and ' ' for sign control, '0' for space or zero padding, and '-' for left or right justification. It does not support precision. See the fmt package for details.

func (*Decimal) Int64

func (d *Decimal) Int64() (int64, error)

Int64 returns the int64 representation of x. If x cannot be represented in an int64, an error is returned.

func (*Decimal) IsZero

func (d *Decimal) IsZero() bool

IsZero returns true if d == 0 or -0.

func (*Decimal) MarshalText

func (d *Decimal) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*Decimal) Modf

func (d *Decimal) Modf(integ, frac *Decimal)

Modf sets integ to the integral part of d and frac to the fractional part such that d = integ+frac. If d is negative, both integ or frac will be either 0 or negative. integ.Exponent will be >= 0; frac.Exponent will be <= 0. Either argument can be nil, preventing it from being set.

func (*Decimal) Neg

func (d *Decimal) Neg(x *Decimal) *Decimal

Neg sets d to -x and returns d.

func (*Decimal) NumDigits

func (d *Decimal) NumDigits() int64

NumDigits returns the number of decimal digits of d.Coeff.

func (*Decimal) Reduce

func (d *Decimal) Reduce(x *Decimal) (*Decimal, int)

Reduce sets d to x with all trailing zeros removed and returns d and the number of zeros removed.

func (*Decimal) Scan

func (d *Decimal) Scan(src interface{}) error

Scan implements the database/sql.Scanner interface. It supports string, []byte, int64, float64.

func (*Decimal) Set

func (d *Decimal) Set(x *Decimal) *Decimal

Set sets d's fields to the values of x and returns d.

func (*Decimal) SetFinite

func (d *Decimal) SetFinite(x int64, e int32) *Decimal

SetFinite sets d to x with exponent e and returns d.

func (*Decimal) SetFloat64

func (d *Decimal) SetFloat64(f float64) (*Decimal, error)

SetFloat64 sets d's Coefficient and Exponent to x and returns d. d will hold the exact value of f.

func (*Decimal) SetInt64

func (d *Decimal) SetInt64(x int64) *Decimal

SetInt64 sets d to x and returns d.

func (*Decimal) SetString

func (d *Decimal) SetString(s string) (*Decimal, Condition, error)

SetString sets d to s and returns d. It has no restrictions on exponents or precision.

func (*Decimal) Sign

func (d *Decimal) Sign() int

Sign returns, if d is Finite:

-1 if d <  0
 0 if d == 0 or -0
+1 if d >  0

Otherwise (if d is Infinite or NaN):

-1 if d.Negative == true
+1 if d.Negative == false

func (*Decimal) Size

func (d *Decimal) Size() uintptr

Size returns the total memory footprint of d in bytes.

func (*Decimal) String

func (d *Decimal) String() string

String formats x like x.Text('G'). It matches the to-scientific-string conversion of the GDA spec.

func (*Decimal) Text

func (d *Decimal) Text(format byte) string

Text converts the floating-point number x to a string according to the given format. The format is one of:

'e'	-d.dddde±dd, decimal exponent, exponent digits
'E'	-d.ddddE±dd, decimal exponent, exponent digits
'f'	-ddddd.dddd, no exponent
'g'	like 'e' for large exponents, like 'f' otherwise
'G'	like 'E' for large exponents, like 'f' otherwise

If format is a different character, Text returns a "%" followed by the unrecognized.Format character. The 'f' format has the possibility of displaying precision that is not present in the Decimal when it appends zeros (the 'g' format avoids the use of 'f' in this case). All other formats always show the exact precision of the Decimal.

func (*Decimal) UnmarshalText

func (d *Decimal) UnmarshalText(b []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (Decimal) Value

func (d Decimal) Value() (driver.Value, error)

Value implements the database/sql/driver.Valuer interface. It converts d to a string.

type ErrDecimal

type ErrDecimal struct {
	Ctx *Context
	// Flags are the accumulated flags from operations.
	Flags Condition
	// contains filtered or unexported fields
}

ErrDecimal performs operations on decimals and collects errors during operations. If an error is already set, the operation is skipped. Designed to be used for many operations in a row, with a single error check at the end.

Example
c := apd.BaseContext.WithPrecision(5)
ed := apd.MakeErrDecimal(c)
d := apd.New(10, 0)
fmt.Printf("%s, err: %v\n", d, ed.Err())
ed.Add(d, d, apd.New(2, 1)) // add 20
fmt.Printf("%s, err: %v\n", d, ed.Err())
ed.Quo(d, d, apd.New(0, 0)) // divide by zero
fmt.Printf("%s, err: %v\n", d, ed.Err())
ed.Sub(d, d, apd.New(1, 0)) // attempt to subtract 1
// The subtraction doesn't occur and doesn't change the error.
fmt.Printf("%s, err: %v\n", d, ed.Err())
Output:

10, err: <nil>
30, err: <nil>
Infinity, err: division by zero
Infinity, err: division by zero

func MakeErrDecimal

func MakeErrDecimal(c *Context) ErrDecimal

MakeErrDecimal creates a ErrDecimal with given context.

func (*ErrDecimal) Abs

func (e *ErrDecimal) Abs(d, x *Decimal) *Decimal

Abs performs e.Ctx.Abs(d, x) and returns d.

func (*ErrDecimal) Add

func (e *ErrDecimal) Add(d, x, y *Decimal) *Decimal

Add performs e.Ctx.Add(d, x, y) and returns d.

func (*ErrDecimal) Ceil

func (e *ErrDecimal) Ceil(d, x *Decimal) *Decimal

Ceil performs e.Ctx.Ceil(d, x) and returns d.

func (*ErrDecimal) Err

func (e *ErrDecimal) Err() error

Err returns the first error encountered or the context's trap error if present.

func (*ErrDecimal) Exp

func (e *ErrDecimal) Exp(d, x *Decimal) *Decimal

Exp performs e.Ctx.Exp(d, x) and returns d.

func (*ErrDecimal) Floor

func (e *ErrDecimal) Floor(d, x *Decimal) *Decimal

Floor performs e.Ctx.Floor(d, x) and returns d.

func (*ErrDecimal) Int64

func (e *ErrDecimal) Int64(d *Decimal) int64

Int64 returns 0 if err is set. Otherwise returns d.Int64().

func (*ErrDecimal) Ln

func (e *ErrDecimal) Ln(d, x *Decimal) *Decimal

Ln performs e.Ctx.Ln(d, x) and returns d.

func (*ErrDecimal) Log10

func (e *ErrDecimal) Log10(d, x *Decimal) *Decimal

Log10 performs d.Log10(x) and returns d.

func (*ErrDecimal) Mul

func (e *ErrDecimal) Mul(d, x, y *Decimal) *Decimal

Mul performs e.Ctx.Mul(d, x, y) and returns d.

func (*ErrDecimal) Neg

func (e *ErrDecimal) Neg(d, x *Decimal) *Decimal

Neg performs e.Ctx.Neg(d, x) and returns d.

func (*ErrDecimal) Pow

func (e *ErrDecimal) Pow(d, x, y *Decimal) *Decimal

Pow performs e.Ctx.Pow(d, x, y) and returns d.

func (*ErrDecimal) Quantize

func (e *ErrDecimal) Quantize(d, v *Decimal, exp int32) *Decimal

Quantize performs e.Ctx.Quantize(d, v, exp) and returns d.

func (*ErrDecimal) Quo

func (e *ErrDecimal) Quo(d, x, y *Decimal) *Decimal

Quo performs e.Ctx.Quo(d, x, y) and returns d.

func (*ErrDecimal) QuoInteger

func (e *ErrDecimal) QuoInteger(d, x, y *Decimal) *Decimal

QuoInteger performs e.Ctx.QuoInteger(d, x, y) and returns d.

func (*ErrDecimal) Reduce

func (e *ErrDecimal) Reduce(d, x *Decimal) (int, *Decimal)

Reduce performs e.Ctx.Reduce(d, x) and returns the number of zeros removed and d.

func (*ErrDecimal) Rem

func (e *ErrDecimal) Rem(d, x, y *Decimal) *Decimal

Rem performs e.Ctx.Rem(d, x, y) and returns d.

func (*ErrDecimal) Round

func (e *ErrDecimal) Round(d, x *Decimal) *Decimal

Round performs e.Ctx.Round(d, x) and returns d.

func (*ErrDecimal) RoundToIntegralExact

func (e *ErrDecimal) RoundToIntegralExact(d, x *Decimal) *Decimal

RoundToIntegralExact performs e.Ctx.RoundToIntegralExact(d, x) and returns d.

func (*ErrDecimal) RoundToIntegralValue

func (e *ErrDecimal) RoundToIntegralValue(d, x *Decimal) *Decimal

RoundToIntegralValue performs e.Ctx.RoundToIntegralValue(d, x) and returns d.

func (*ErrDecimal) Sqrt

func (e *ErrDecimal) Sqrt(d, x *Decimal) *Decimal

Sqrt performs e.Ctx.Sqrt(d, x) and returns d.

func (*ErrDecimal) Sub

func (e *ErrDecimal) Sub(d, x, y *Decimal) *Decimal

Sub performs e.Ctx.Sub(d, x, y) and returns d.

type Form

type Form int8

Form specifies the form of a Decimal.

const (

	// Finite is the finite form.
	Finite Form = iota
	// Infinite is the infinite form.
	Infinite
	// NaNSignaling is the signaling NaN form. It will always raise the
	// InvalidOperation condition during an operation.
	NaNSignaling
	// NaN is the NaN form.
	NaN
)

func (Form) String

func (i Form) String() string

type NullDecimal

type NullDecimal struct {
	Decimal Decimal
	Valid   bool // Valid is true if Decimal is not NULL
}

NullDecimal represents a string that may be null. NullDecimal implements the database/sql.Scanner interface so it can be used as a scan destination:

var d NullDecimal
err := db.QueryRow("SELECT num FROM foo WHERE id=?", id).Scan(&d)
...
if d.Valid {
   // use d.Decimal
} else {
   // NULL value
}

func (*NullDecimal) Scan

func (nd *NullDecimal) Scan(value interface{}) error

Scan implements the database/sql.Scanner interface.

func (NullDecimal) Value

func (nd NullDecimal) Value() (driver.Value, error)

Value implements the database/sql/driver.Valuer interface.

type Rounder

type Rounder string

Rounder specifies the behavior of rounding.

const (
	// RoundDown rounds toward 0; truncate.
	RoundDown Rounder = "down"
	// RoundHalfUp rounds up if the digits are >= 0.5.
	RoundHalfUp Rounder = "half_up"
	// RoundHalfEven rounds up if the digits are > 0.5. If the digits are equal
	// to 0.5, it rounds up if the previous digit is odd, always producing an
	// even digit.
	RoundHalfEven Rounder = "half_even"
	// RoundCeiling towards +Inf: rounds up if digits are > 0 and the number
	// is positive.
	RoundCeiling Rounder = "ceiling"
	// RoundFloor towards -Inf: rounds up if digits are > 0 and the number
	// is negative.
	RoundFloor Rounder = "floor"
	// RoundHalfDown rounds up if the digits are > 0.5.
	RoundHalfDown Rounder = "half_down"
	// RoundUp rounds away from 0.
	RoundUp Rounder = "up"
	// Round05Up rounds zero or five away from 0; same as round-up, except that
	// rounding up only occurs if the digit to be rounded up is 0 or 5.
	Round05Up Rounder = "05up"
)

func (Rounder) Round

func (r Rounder) Round(c *Context, d, x *Decimal, disableIfPrecisionZero bool) Condition

Round sets d to rounded x.

func (Rounder) ShouldAddOne

func (r Rounder) ShouldAddOne(result *BigInt, neg bool, half int) bool

ShouldAddOne returns true if 1 should be added to the absolute value of a number being rounded. result is the result to which the 1 would be added. neg is true if the number is negative. half is -1 if the discarded digits are < 0.5, 0 if = 0.5, or 1 if > 0.5.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL