-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
doc.go
107 lines (76 loc) · 4.42 KB
/
doc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright 2020 Denis Bernard <db047h@gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package decimal implements arbitrary-precision decimal floating-point
arithmetic.
The implementation is heavily based on big.Float and the API is identical to
that of *big.Float with the exception of a few additional getters and setters,
an FMA operation, and helper functions to support implementation of missing
low-level Decimal functionality outside this package (see the math sub-package).
Howvever, and unlike big.Float, the mantissa of a decimal is stored in a
little-endian Word slice as "declets" of 9 or 19 decimal digits per 32 or 64
bits Word. All arithmetic operations are performed directly in base 10**9 or
10**19 without conversion to/from binary.
The mantissa of a Decimal is always normalized, that is the most significant
digit of the mantissa is always a non-zero digit and:
0.1 <= mantissa < 1 (1)
The bounds for a finite Dicimal x are:
0.1 × 10**MinExp <= x < 1 × 10**MaxExp (2)
As a consequence to points (1) and (2), and unlike in the IEEE-754 standard, a
finite Decimal can only be a normal number (no subnormal numbers) and there is
no Quantize operation.
The zero value for a Decimal corresponds to 0. Thus, new values can be declared
in the usual ways and denote 0 without further initialization:
x := new(Decimal) // x is a *Decimal of value 0
Alternatively, new Decimal values can be allocated and initialized with the
function:
func NewDecimal(x int64, exp int) *Decimal
NewDecimal(x, exp) returns a *Decimal set to the value of x×10**exp. More
flexibility is provided with explicit setters, for instance:
z := new(Decimal).SetUint64(123) // z3 := 123.0
Setters, numeric operations and predicates are represented as methods of the
form:
func (z *Decimal) SetV(v V) *Decimal // z = v
func (z *Decimal) Unary(x *Decimal) *Decimal // z = unary x
func (z *Decimal) Binary(x, y *Decimal) *Decimal // z = x binary y
func (x *Decimal) Pred() P // p = pred(x)
For unary and binary operations, the result is the receiver (usually named z in
that case; see below); if it is one of the operands x or y it may be safely
overwritten (and its memory reused).
Arithmetic expressions are typically written as a sequence of individual method
calls, with each call corresponding to an operation. The receiver denotes the
result and the method arguments are the operation's operands. For instance,
given three *Decimal values a, b and c, the invocation
c.Add(a, b)
computes the sum a + b and stores the result in c, overwriting whatever value
was held in c before. Unless specified otherwise, operations permit aliasing of
parameters, so it is perfectly ok to write
sum.Add(sum, x)
to accumulate values x in a sum.
(By always passing in a result value via the receiver, memory use can be much
better controlled. Instead of having to allocate new memory for each result, an
operation can reuse the space allocated for the result value, and overwrite that
value with the new result in the process.)
Notational convention: Incoming method parameters (including the receiver) are
named consistently in the API to clarify their use. Incoming operands are
usually named x, y, a, b, and so on, but never z. A parameter specifying the
result is named z (typically the receiver).
For instance, the arguments for (*Decimal).Add are named x and y, and because
the receiver specifies the result destination, it is called z:
func (z *Decimal) Add(x, y *Decimal) *Decimal
Methods of this form typically return the incoming receiver as well, to enable
simple call chaining.
Methods which don't require a result value to be passed in (for instance,
Decimal.Sign), simply return the result. In this case, the receiver is typically
the first operand, named x:
func (x *Decimal) Sign() int
Various methods support conversions between strings and corresponding numeric
values, and vice versa: Decimal implements the Stringer interface for a
(default) string representation of the value, but also provides SetString
methods to initialize a Decimal value from a string in a variety of supported
formats (see the SetString documentation).
Finally, *Decimal satisfies the fmt package's Scanner interface for scanning and
the Formatter interface for formatted printing.
*/
package decimal