# inf

package
Version: v0.5.1 Latest Latest

Go to latest
Published: Mar 26, 2015

## Documentation ¶

### Overview ¶

Package inf (type inf.Dec) implements "infinite-precision" decimal arithmetic. "Infinite precision" describes two characteristics: practically unlimited precision for decimal number representation and no support for calculating with any specific fixed precision. (Although there is no practical limit on precision, inf.Dec can only represent finite decimals.)

This package is currently in experimental stage and the API may change.

This package does NOT support:

```- rounding to specific precisions (as opposed to specific decimal positions)
- the notion of context (each rounding must be explicit)
- NaN and Inf values, and distinguishing between positive and negative zero
- conversions to and from float32/64 types
```

```+ formatting options
+ Exp method
+ exchanging data in decimal32/64/128 formats
```

### Constants ¶

This section is empty.

### Variables ¶

This section is empty.

### Functions ¶

This section is empty.

### Types ¶

#### type Dec ¶

```type Dec struct {
// contains filtered or unexported fields
}```

A Dec represents a signed arbitrary-precision decimal. It is a combination of a sign, an arbitrary-precision integer coefficient value, and a signed fixed-precision exponent value. The sign and the coefficient value are handled together as a signed value and referred to as the unscaled value. (Positive and negative zero values are not distinguished.) Since the exponent is most commonly non-positive, it is handled in negated form and referred to as scale.

The mathematical value of a Dec equals:

```unscaled * 10**(-scale)
```

Note that different Dec representations may have equal mathematical values.

```unscaled  scale  String()
-------------------------
0      0    "0"
0      2    "0.00"
0     -2    "0"
1      0    "1"
100      2    "1.00"
10      0   "10"
1     -1   "10"
```

The zero value for a Dec represents the value 0 with scale 0.

Operations are typically performed through the *Dec type. The semantics of the assignment operation "=" for "bare" Dec values is undefined and should not be relied on.

Methods are typically of the form:

```func (z *Dec) Op(x, y *Dec) *Dec
```

and implement operations z = x Op y with the result as receiver; if it is one of the operands it may be overwritten (and its memory reused). To enable chaining of operations, the result is also returned. Methods returning a result other than *Dec take one of the operands as the receiver.

A "bare" Quo method (quotient / division operation) is not provided, as the result is not always a finite decimal and thus in general cannot be represented as a Dec. Instead, in the common case when rounding is (potentially) necessary, QuoRound should be used with a Scale and a Rounder. QuoExact or QuoRound with RoundExact can be used in the special cases when it is known that the result is always a finite decimal.

#### func NewDec ¶

`func NewDec(unscaled int64, scale Scale) *Dec`

NewDec allocates and returns a new Dec set to the given int64 unscaled value and scale.

#### func NewDecBig ¶

`func NewDecBig(unscaled *big.Int, scale Scale) *Dec`

NewDecBig allocates and returns a new Dec set to the given *big.Int unscaled value and scale.

#### func (*Dec) Abs ¶

`func (z *Dec) Abs(x *Dec) *Dec`

Abs sets z to |x| (the absolute value of x) and returns z.

`func (z *Dec) Add(x, y *Dec) *Dec`

Add sets z to the sum x+y and returns z. The scale of z is the greater of the scales of x and y.

#### func (*Dec) Cmp ¶

`func (x *Dec) Cmp(y *Dec) int`

Cmp compares x and y and returns:

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

#### func (*Dec) Format ¶

`func (x *Dec) Format(s fmt.State, ch rune)`

Format is a support routine for fmt.Formatter. It accepts the decimal formats 'd' and 'f', and handles both equivalently. Width, precision, flags and bases 2, 8, 16 are not supported.

#### func (*Dec) GobDecode ¶

`func (z *Dec) GobDecode(buf []byte) error`

GobDecode implements the gob.GobDecoder interface.

#### func (*Dec) GobEncode ¶

`func (x *Dec) GobEncode() ([]byte, error)`

GobEncode implements the gob.GobEncoder interface.

#### func (*Dec) MarshalText ¶

`func (x *Dec) MarshalText() ([]byte, error)`

MarshalText implements the encoding.TextMarshaler interface.

#### func (*Dec) Mul ¶

`func (z *Dec) Mul(x, y *Dec) *Dec`

Mul sets z to the product x*y and returns z. The scale of z is the sum of the scales of x and y.

#### func (*Dec) Neg ¶

`func (z *Dec) Neg(x *Dec) *Dec`

Neg sets z to -x and returns z.

#### func (*Dec) QuoExact ¶

`func (z *Dec) QuoExact(x, y *Dec) *Dec`

QuoExact sets z to the quotient x/y and returns z when x/y is a finite decimal. Otherwise it returns nil and the value of z is undefined.

The scale of a non-nil result is "x.Scale() - y.Scale()" or greater; it is calculated so that the remainder will be zero whenever x/y is a finite decimal.

Example (Fail)
```package main

import (
"fmt"

"github.com/coreos/rocket/Godeps/_workspace/src/speter.net/go/exp/math/dec/inf"
)

func main() {
// 1 / 3 is an infinite decimal; it has no exact Dec representation
x, y := inf.NewDec(1, 0), inf.NewDec(3, 0)
z := new(inf.Dec).QuoExact(x, y)
fmt.Println(z)
}
```
```Output:

<nil>
```
Example (Ok)
```package main

import (
"fmt"

"github.com/coreos/rocket/Godeps/_workspace/src/speter.net/go/exp/math/dec/inf"
)

func main() {
// 1 / 25 is a finite decimal; it has exact Dec representation
x, y := inf.NewDec(1, 0), inf.NewDec(25, 0)
z := new(inf.Dec).QuoExact(x, y)
fmt.Println(z)
}
```
```Output:

0.04
```

#### func (*Dec) QuoRound ¶

`func (z *Dec) QuoRound(x, y *Dec, s Scale, r Rounder) *Dec`

QuoRound sets z to the quotient x/y, rounded using the given Rounder to the specified scale.

If the rounder is RoundExact but the result can not be expressed exactly at the specified scale, QuoRound returns nil, and the value of z is undefined.

There is no corresponding Div method; the equivalent can be achieved through the choice of Rounder used.

Example (Scale2RoundCeil)
```package main

import (
"fmt"

"github.com/coreos/rocket/Godeps/_workspace/src/speter.net/go/exp/math/dec/inf"
)

func main() {
// -42 / 400 is an finite decimal with 3 digits beyond the decimal point
x, y := inf.NewDec(-42, 0), inf.NewDec(400, 0)
// use 2 digits beyond decimal point, round towards positive infinity
z := new(inf.Dec).QuoRound(x, y, 2, inf.RoundCeil)
fmt.Println(z)
}
```
```Output:

-0.10
```
Example (Scale2RoundDown)
```package main

import (
"fmt"

"github.com/coreos/rocket/Godeps/_workspace/src/speter.net/go/exp/math/dec/inf"
)

func main() {
// 10 / 3 is an infinite decimal; it has no exact Dec representation
x, y := inf.NewDec(10, 0), inf.NewDec(3, 0)
// use 2 digits beyond the decimal point, round towards 0
z := new(inf.Dec).QuoRound(x, y, 2, inf.RoundDown)
fmt.Println(z)
}
```
```Output:

3.33
```

#### func (*Dec) Round ¶

`func (z *Dec) Round(x *Dec, s Scale, r Rounder) *Dec`

Round sets z to the value of x rounded to Scale s using Rounder r, and returns z.

#### func (*Dec) Scale ¶

`func (x *Dec) Scale() Scale`

Scale returns the scale of x.

#### func (*Dec) Scan ¶

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

Scan is a support routine for fmt.Scanner; it sets z to the value of the scanned number. It accepts the decimal formats 'd' and 'f', and handles both equivalently. Bases 2, 8, 16 are not supported. The scale of z is the number of digits after the decimal point (including any trailing 0s), or 0 if there is no decimal point.

Example
```package main

import (
"fmt"
"log"

"github.com/coreos/rocket/Godeps/_workspace/src/speter.net/go/exp/math/dec/inf"
)

func main() {
// The Scan function is rarely used directly;
// the fmt package recognizes it as an implementation of fmt.Scanner.
d := new(inf.Dec)
_, err := fmt.Sscan("184467440.73709551617", d)
if err != nil {
log.Println("error scanning value:", err)
} else {
fmt.Println(d)
}
}
```
```Output:

184467440.73709551617
```

#### func (*Dec) Set ¶

`func (z *Dec) Set(x *Dec) *Dec`

Set sets z to the value of x and returns z. It does nothing if z == x.

#### func (*Dec) SetScale ¶

`func (z *Dec) SetScale(scale Scale) *Dec`

SetScale sets the scale of z, with the unscaled value unchanged, and returns z. The mathematical value of the Dec changes as if it was multiplied by 10**(oldscale-scale).

#### func (*Dec) SetString ¶

`func (z *Dec) SetString(s string) (*Dec, bool)`

SetString sets z to the value of s, interpreted as a decimal (base 10), and returns z and a boolean indicating success. The scale of z is the number of digits after the decimal point (including any trailing 0s), or 0 if there is no decimal point. If SetString fails, the value of z is undefined but the returned value is nil.

Example
```package main

import (
"fmt"

"github.com/coreos/rocket/Godeps/_workspace/src/speter.net/go/exp/math/dec/inf"
)

func main() {
d := new(inf.Dec)
d.SetString("012345.67890") // decimal; leading 0 ignored; trailing 0 kept
fmt.Println(d)
}
```
```Output:

12345.67890
```

#### func (*Dec) SetUnscaled ¶

`func (z *Dec) SetUnscaled(unscaled int64) *Dec`

SetUnscaled sets the unscaled value of z, with the scale unchanged, and returns z.

#### func (*Dec) SetUnscaledBig ¶

`func (z *Dec) SetUnscaledBig(unscaled *big.Int) *Dec`

SetUnscaledBig sets the unscaled value of z, with the scale unchanged, and returns z.

#### func (*Dec) Sign ¶

`func (x *Dec) Sign() int`

Sign returns:

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

#### func (*Dec) String ¶

`func (x *Dec) String() string`

#### func (*Dec) Sub ¶

`func (z *Dec) Sub(x, y *Dec) *Dec`

Sub sets z to the difference x-y and returns z. The scale of z is the greater of the scales of x and y.

#### func (*Dec) UnmarshalText ¶

`func (z *Dec) UnmarshalText(data []byte) error`

UnmarshalText implements the encoding.TextUnmarshaler interface.

#### func (*Dec) Unscaled ¶

`func (x *Dec) Unscaled() (u int64, ok bool)`

Unscaled returns the unscaled value of x for u and true for ok when the unscaled value can be represented as int64; otherwise it returns an undefined int64 value for u and false for ok. Use x.UnscaledBig().Int64() to avoid checking the validity of the value when the check is known to be redundant.

#### func (*Dec) UnscaledBig ¶

`func (x *Dec) UnscaledBig() *big.Int`

UnscaledBig returns the unscaled value of x as *big.Int.

#### type Rounder ¶

`type Rounder rounder`

Rounder represents a method for rounding the (possibly infinite decimal) result of a division to a finite Dec. It is used by Dec.Round() and Dec.Quo().

See the Example for results of using each Rounder with some sample values.

Example

This example displays the results of Dec.Round with each of the Rounders.

```package main

import (
"fmt"
"os"
"text/tabwriter"

"github.com/coreos/rocket/Godeps/_workspace/src/speter.net/go/exp/math/dec/inf"
)

func main() {
var vals = []struct {
x string
s inf.Scale
}{
{"-0.18", 1}, {"-0.15", 1}, {"-0.12", 1}, {"-0.10", 1},
{"-0.08", 1}, {"-0.05", 1}, {"-0.02", 1}, {"0.00", 1},
{"0.02", 1}, {"0.05", 1}, {"0.08", 1}, {"0.10", 1},
{"0.12", 1}, {"0.15", 1}, {"0.18", 1},
}

var rounders = []struct {
name    string
rounder inf.Rounder
}{
{"RoundDown", inf.RoundDown}, {"RoundUp", inf.RoundUp},
{"RoundCeil", inf.RoundCeil}, {"RoundFloor", inf.RoundFloor},
{"RoundHalfDown", inf.RoundHalfDown}, {"RoundHalfUp", inf.RoundHalfUp},
{"RoundHalfEven", inf.RoundHalfEven}, {"RoundExact", inf.RoundExact},
}

fmt.Println("The results of new(inf.Dec).Round(x, s, inf.RoundXXX):\n")
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.AlignRight)
fmt.Fprint(w, "x\ts\t|\t")
for _, r := range rounders {
fmt.Fprintf(w, "%s\t", r.name[5:])
}
fmt.Fprintln(w)
for _, v := range vals {
fmt.Fprintf(w, "%s\t%d\t|\t", v.x, v.s)
for _, r := range rounders {
x, _ := new(inf.Dec).SetString(v.x)
z := new(inf.Dec).Round(x, v.s, r.rounder)
fmt.Fprintf(w, "%d\t", z)
}
fmt.Fprintln(w)
}
w.Flush()

}
```
```Output:

The results of new(inf.Dec).Round(x, s, inf.RoundXXX):

x s | Down   Up Ceil Floor HalfDown HalfUp HalfEven Exact
-0.18 1 | -0.1 -0.2 -0.1  -0.2     -0.2   -0.2     -0.2 <nil>
-0.15 1 | -0.1 -0.2 -0.1  -0.2     -0.1   -0.2     -0.2 <nil>
-0.12 1 | -0.1 -0.2 -0.1  -0.2     -0.1   -0.1     -0.1 <nil>
-0.10 1 | -0.1 -0.1 -0.1  -0.1     -0.1   -0.1     -0.1  -0.1
-0.08 1 |  0.0 -0.1  0.0  -0.1     -0.1   -0.1     -0.1 <nil>
-0.05 1 |  0.0 -0.1  0.0  -0.1      0.0   -0.1      0.0 <nil>
-0.02 1 |  0.0 -0.1  0.0  -0.1      0.0    0.0      0.0 <nil>
0.00 1 |  0.0  0.0  0.0   0.0      0.0    0.0      0.0   0.0
0.02 1 |  0.0  0.1  0.1   0.0      0.0    0.0      0.0 <nil>
0.05 1 |  0.0  0.1  0.1   0.0      0.0    0.1      0.0 <nil>
0.08 1 |  0.0  0.1  0.1   0.0      0.1    0.1      0.1 <nil>
0.10 1 |  0.1  0.1  0.1   0.1      0.1    0.1      0.1   0.1
0.12 1 |  0.1  0.2  0.2   0.1      0.1    0.1      0.1 <nil>
0.15 1 |  0.1  0.2  0.2   0.1      0.1    0.2      0.2 <nil>
0.18 1 |  0.1  0.2  0.2   0.1      0.2    0.2      0.2 <nil>
```
```var (
RoundDown     Rounder // towards 0
RoundUp       Rounder // away from 0
RoundFloor    Rounder // towards -infinity
RoundCeil     Rounder // towards +infinity
RoundHalfDown Rounder // to nearest; towards 0 if same distance
RoundHalfUp   Rounder // to nearest; away from 0 if same distance
RoundHalfEven Rounder // to nearest; even last digit if same distance
)```

See http://speleotrove.com/decimal/damodel.html#refround for more detailed definitions of these rounding modes.

`var RoundExact Rounder`

RoundExact is to be used in the case when rounding is not necessary. When used with Quo or Round, it returns the result verbatim when it can be expressed exactly with the given precision, and it returns nil otherwise. QuoExact is a shorthand for using Quo with RoundExact.

#### type Scale ¶

`type Scale int32`

Scale represents the type used for the scale of a Dec.