-
Notifications
You must be signed in to change notification settings - Fork 1
/
bigdecimal.go
132 lines (105 loc) · 3.03 KB
/
bigdecimal.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package lang
import (
"fmt"
"math/big"
"bitbucket.org/pcastools/hash"
)
// BigDec is an arbitrary-precision decimal number. It wraps and has
// the same semantics as big.Float. big.Float is not used directly
// because it is mutable, and the core BigDecimal should not be.
type BigDecimal struct {
val *big.Float
}
// NewBigDecimal creates a new BigDecimal from a string.
func NewBigDecimal(s string) (*BigDecimal, error) {
bf, ok := new(big.Float).SetString(s)
if !ok {
return nil, fmt.Errorf("invalid big decimal: %s", s)
}
return &BigDecimal{val: bf}, nil
}
// NewBigDecimalFromBigFloat
func NewBigDecimalFromBigFloat(x *big.Float) *BigDecimal {
xCopy := new(big.Float)
xCopy.Set(x)
return &BigDecimal{val: xCopy}
}
// NewBigDecimalFromFloat64 creates a new BigDecimal from a float64.
func NewBigDecimalFromFloat64(x float64) *BigDecimal {
return &BigDecimal{val: new(big.Float).SetFloat64(x)}
}
func NewBigDecimalFromInt64(x int64) *BigDecimal {
return &BigDecimal{val: new(big.Float).SetInt64(x)}
}
func (n *BigDecimal) ToBigInteger() *big.Int {
res, _ := n.val.Int(nil)
return res
}
func (n *BigDecimal) String() string {
return n.val.String()
}
func (n *BigDecimal) Hash() uint32 {
if n.val.Sign() == 0 {
return 0
}
return hash.String(n.val.String())
}
func (n *BigDecimal) Equals(v interface{}) bool {
other, ok := v.(*BigDecimal)
if !ok {
return false
}
return n.val.Cmp(other.val) == 0
}
func (n *BigDecimal) AddInt(x int) *BigDecimal {
return &BigDecimal{val: new(big.Float).Add(n.val, big.NewFloat(float64(x)))}
}
func (n *BigDecimal) Add(other *BigDecimal) *BigDecimal {
return &BigDecimal{val: new(big.Float).Add(n.val, other.val)}
}
func (n *BigDecimal) AddP(other *BigDecimal) *BigDecimal {
return n.Add(other)
}
func (n *BigDecimal) Sub(other *BigDecimal) *BigDecimal {
return &BigDecimal{val: new(big.Float).Sub(n.val, other.val)}
}
func (n *BigDecimal) SubP(other *BigDecimal) *BigDecimal {
return n.Sub(other)
}
func (n *BigDecimal) Multiply(other *BigDecimal) *BigDecimal {
return &BigDecimal{val: new(big.Float).Mul(n.val, other.val)}
}
func (n *BigDecimal) Divide(other *BigDecimal) *BigDecimal {
// Todo: div
return &BigDecimal{val: new(big.Float).Quo(n.val, other.val)}
}
func (n *BigDecimal) Quotient(other *BigDecimal) *BigDecimal {
return &BigDecimal{val: new(big.Float).Quo(n.val, other.val)}
}
func (n *BigDecimal) Remainder(other *BigDecimal) *BigDecimal {
panic("not implemented")
}
func (n *BigDecimal) Cmp(other *BigDecimal) int {
return n.val.Cmp(other.val)
}
func (n *BigDecimal) LT(other *BigDecimal) bool {
return n.Cmp(other) < 0
}
func (n *BigDecimal) LTE(other *BigDecimal) bool {
return n.Cmp(other) <= 0
}
func (n *BigDecimal) GT(other *BigDecimal) bool {
return n.Cmp(other) > 0
}
func (n *BigDecimal) GTE(other *BigDecimal) bool {
return n.Cmp(other) >= 0
}
func (n *BigDecimal) Negate() *BigDecimal {
return &BigDecimal{val: new(big.Float).Neg(n.val)}
}
func (n *BigDecimal) Abs() *BigDecimal {
if n.val.Sign() < 0 {
return &BigDecimal{val: new(big.Float).Abs(n.val)}
}
return n
}