-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdecimal_test.go
91 lines (86 loc) · 2.51 KB
/
decimal_test.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
package decimal
import (
"math/big"
"math/bits"
"math/rand"
"reflect"
"strconv"
"testing"
"time"
)
var intData = []struct {
s string
p uint
d dec
pr uint
e int32
}{
{"1234567890123456789_0123456789012345678_9012345678901234567_8901234567890123456_78901234567890", 0,
dec{7890123456789000000, 8901234567890123456, 9012345678901234567, 123456789012345678, 1234567890123456789},
90, 90},
{"1235", 0, dec{1235000000000000000}, _WD, 4},
{"1235", 3, dec{1240000000000000000}, 3, 4},
{"1245", 3, dec{1240000000000000000}, 3, 4},
{"12451", 3, dec{1250000000000000000}, 3, 5},
{"0", 0, nil, _WD, 0},
}
func TestDnorm(t *testing.T) {
rand.Seed(time.Now().UnixNano())
for i := 0; i < 10000; i++ {
again:
w := uint(rand.Uint64()) % _BD
e := uint(rand.Intn(_WD + 1))
h, l := bits.Mul(w, pow10(e))
// convert h, l from base _B (2**64) to base _BD (10**19) or 2**32 -> 10**9
h, l = bits.Div(h, l, _BD)
d := dec{Word(l), Word(h)}.norm()
if len(d) == 0 {
if w == 0 {
goto again
}
t.Fatalf("dec{%v, %v}).norm() returned dec{} for word %d", l, h, w)
}
dd := dec{}.set(d)
s := dnorm(dd)
// d should now have a single element with e shifted left
ew := w * pow10(_WD-mag(w))
es := int64(uint(len(d)*_WD) - (mag(w) + e))
if dd[len(dd)-1] != Word(ew) || s != es {
t.Fatalf("%ve%v => dnorm(%v) = %v, %v --- Expected %d, %d",
w, e, d, dd, s, w, es)
}
}
}
func TestDecimal_SetInt(t *testing.T) {
for i, td := range intData {
t.Run(strconv.Itoa(i), func(t *testing.T) {
b, _ := new(big.Int).SetString(td.s, 0)
d := new(Decimal).SetMode(ToNearestEven).SetPrec(td.p).SetInt(b)
if !reflect.DeepEqual(td.d, d.mant) {
t.Fatalf("\nexpected mantissa %v\n got %v", td.d, d.mant)
}
if td.pr != d.Prec() {
t.Fatalf("\nexpected precision %v\n got %v", td.pr, d.Prec())
}
if td.e != d.exp {
t.Fatalf("\nexpected exponent %v\n got %v", td.p, d.Prec())
}
})
}
}
func TestDecimal_SetString(t *testing.T) {
// for i, td := range intData {
// t.Run(strconv.Itoa(i), func(t *testing.T) {
// d, _ := new(Decimal).SetMode(ToNearestEven).SetPrec(td.p).SetString(td.s)
// if !reflect.DeepEqual(td.d, d.mant) {
// t.Fatalf("\nexpected mantissa %v\n got %v", td.d, d.mant)
// }
// if td.pr != d.Prec() {
// t.Fatalf("\nexpected precision %v\n got %v", td.pr, d.Prec())
// }
// if td.e != d.exp {
// t.Fatalf("\nexpected exponent %v\n got %v", td.p, d.Prec())
// }
// })
// }
}