1
2
3
4
5 package strconv_test
6
7 import (
8 . "internal/strconv"
9 "math"
10 "testing"
11 )
12
13 var pow10Tests = []struct {
14 exp10 int
15 mant uint128
16 exp2 int
17 ok bool
18 }{
19 {-349, uint128{0, 0}, 0, false},
20 {-348, uint128{0xFA8FD5A0081C0288, 0x1732C869CD60E453}, -1156, true},
21 {0, uint128{0x8000000000000000, 0x0000000000000000}, 1, true},
22 {347, uint128{0xD13EB46469447567, 0x4B7195F2D2D1A9FB}, 1153, true},
23 {348, uint128{0, 0}, 0, false},
24 }
25
26 func TestPow10(t *testing.T) {
27 for _, tt := range pow10Tests {
28 mant, exp2, ok := pow10(tt.exp10)
29 if mant != tt.mant || exp2 != tt.exp2 {
30 t.Errorf("pow10(%d) = %#016x, %#016x, %d, %v want %#016x,%#016x, %d, %v",
31 tt.exp10, mant.Hi, mant.Lo, exp2, ok,
32 tt.mant.Hi, tt.mant.Lo, tt.exp2, tt.ok)
33 }
34 }
35
36 for p := pow10Min; p <= pow10Max; p++ {
37 mant, exp2, ok := pow10(p)
38 if !ok {
39 t.Errorf("pow10(%d) not ok", p)
40 continue
41 }
42
43 have := math.Ldexp(float64(mant.Hi), exp2-64)
44 want := math.Pow(10, float64(p))
45 if math.Abs(have-want)/want > 0.00001 {
46 t.Errorf("pow10(%d) = %#016x%016x/2^128 * 2^%d = %g want ~%g", p, mant.Hi, mant.Lo, exp2, have, want)
47 }
48 }
49
50 }
51
52 func u128(hi, lo uint64) uint128 {
53 return uint128{Hi: hi, Lo: lo}
54 }
55
56 var umul192Tests = []struct {
57 x uint64
58 y uint128
59 hi uint64
60 mid uint64
61 lo uint64
62 }{
63 {0, u128(0, 0), 0, 0, 0},
64 {^uint64(0), u128(^uint64(0), ^uint64(0)), ^uint64(1), ^uint64(0), 1},
65 }
66
67 func TestUmul192(t *testing.T) {
68 for _, tt := range umul192Tests {
69 hi, mid, lo := Umul192(tt.x, tt.y)
70 if hi != tt.hi || mid != tt.mid || lo != tt.lo {
71 t.Errorf("umul192(%#x, {%#x,%#x}) = %#x, %#x, %#x, want %#x, %#x, %#x",
72 tt.x, tt.y.Hi, tt.y.Lo, hi, mid, lo, tt.hi, tt.mid, tt.lo)
73 }
74 }
75 }
76
77 func TestMulLog10_2(t *testing.T) {
78 for x := -1600; x <= +1600; x++ {
79 iMath := mulLog10_2(x)
80 fMath := int(math.Floor(float64(x) * math.Ln2 / math.Ln10))
81 if iMath != fMath {
82 t.Errorf("mulLog10_2(%d) failed: %d vs %d\n", x, iMath, fMath)
83 }
84 }
85 }
86
87 func TestMulLog2_10(t *testing.T) {
88 for x := -500; x <= +500; x++ {
89 iMath := mulLog2_10(x)
90 fMath := int(math.Floor(float64(x) * math.Ln10 / math.Ln2))
91 if iMath != fMath {
92 t.Errorf("mulLog2_10(%d) failed: %d vs %d\n", x, iMath, fMath)
93 }
94 }
95 }
96
97 func pow5(p int) uint64 {
98 x := uint64(1)
99 for range p {
100 x *= 5
101 }
102 return x
103 }
104
105 func TestDivisiblePow5(t *testing.T) {
106 for p := 1; p <= 22; p++ {
107 x := pow5(p)
108 if divisiblePow5(1, p) {
109 t.Errorf("divisiblePow5(1, %d) = true, want, false", p)
110 }
111 if divisiblePow5(x-1, p) {
112 t.Errorf("divisiblePow5(%d, %d) = true, want false", x-1, p)
113 }
114 if divisiblePow5(x+1, p) {
115 t.Errorf("divisiblePow5(%d, %d) = true, want false", x-1, p)
116 }
117 if divisiblePow5(x/5, p) {
118 t.Errorf("divisiblePow5(%d, %d) = true, want false", x/5, p)
119 }
120 if !divisiblePow5(0, p) {
121 t.Errorf("divisiblePow5(0, %d) = false, want true", p)
122 }
123 if !divisiblePow5(x, p) {
124 t.Errorf("divisiblePow5(%d, %d) = false, want true", x, p)
125 }
126 if 2*x > x && !divisiblePow5(2*x, p) {
127 t.Errorf("divisiblePow5(%d, %d) = false, want true", 2*x, p)
128 }
129 }
130 }
131
132 func TestDiv5Tab(t *testing.T) {
133 for p := 1; p <= 22; p++ {
134 m := div5Tab[p-1][0]
135 le := div5Tab[p-1][1]
136
137
138
139 if m*pow5(p) != 1 {
140 t.Errorf("pow5Tab[%d-1][0] = %#x, but %#x * (5**%d) = %d, want 1", p, m, m, p, m*pow5(p))
141 }
142
143
144 want := (1<<64 - 1) / pow5(p)
145 if le != want {
146 t.Errorf("pow5Tab[%d-1][1] = %#x, want %#x", p, le, want)
147 }
148 }
149 }
150
151 func TestTrimZeros(t *testing.T) {
152 for _, x := range []uint64{1, 2, 3, 4, 101, 123} {
153 want := x
154 for p := range 20 {
155 haveX, haveP := trimZeros(x)
156 if haveX != want || haveP != p {
157 t.Errorf("trimZeros(%d) = %d, %d, want %d, %d", x, haveX, haveP, want, p)
158 }
159 if x >= (1<<64-1)/10 {
160 break
161 }
162 x *= 10
163 }
164 }
165 }
166
View as plain text