Source file
src/math/big/bits_test.go
1
2
3
4
5
6
7
8
9 package big
10
11 import (
12 "fmt"
13 "slices"
14 "testing"
15 )
16
17
18
19
20
21
22
23
24
25
26 type Bits []int
27
28 func (x Bits) add(y Bits) Bits {
29 return append(x, y...)
30 }
31
32 func (x Bits) mul(y Bits) Bits {
33 var p Bits
34 for _, x := range x {
35 for _, y := range y {
36 p = append(p, x+y)
37 }
38 }
39 return p
40 }
41
42 func TestMulBits(t *testing.T) {
43 for _, test := range []struct {
44 x, y, want Bits
45 }{
46 {nil, nil, nil},
47 {Bits{}, Bits{}, nil},
48 {Bits{0}, Bits{0}, Bits{0}},
49 {Bits{0}, Bits{1}, Bits{1}},
50 {Bits{1}, Bits{1, 2, 3}, Bits{2, 3, 4}},
51 {Bits{-1}, Bits{1}, Bits{0}},
52 {Bits{-10, -1, 0, 1, 10}, Bits{1, 2, 3}, Bits{-9, -8, -7, 0, 1, 2, 1, 2, 3, 2, 3, 4, 11, 12, 13}},
53 } {
54 got := fmt.Sprintf("%v", test.x.mul(test.y))
55 want := fmt.Sprintf("%v", test.want)
56 if got != want {
57 t.Errorf("%v * %v = %s; want %s", test.x, test.y, got, want)
58 }
59
60 }
61 }
62
63
64
65
66 func (x Bits) norm() Bits {
67 m := make(map[int]bool)
68 for _, b := range x {
69 for m[b] {
70 m[b] = false
71 b++
72 }
73 m[b] = true
74 }
75 var z Bits
76 for b, set := range m {
77 if set {
78 z = append(z, b)
79 }
80 }
81 slices.Sort([]int(z))
82 return z
83 }
84
85 func TestNormBits(t *testing.T) {
86 for _, test := range []struct {
87 x, want Bits
88 }{
89 {nil, nil},
90 {Bits{}, Bits{}},
91 {Bits{0}, Bits{0}},
92 {Bits{0, 0}, Bits{1}},
93 {Bits{3, 1, 1}, Bits{2, 3}},
94 {Bits{10, 9, 8, 7, 6, 6}, Bits{11}},
95 } {
96 got := fmt.Sprintf("%v", test.x.norm())
97 want := fmt.Sprintf("%v", test.want)
98 if got != want {
99 t.Errorf("normBits(%v) = %s; want %s", test.x, got, want)
100 }
101
102 }
103 }
104
105
106
107 func (x Bits) round(prec uint, mode RoundingMode) *Float {
108 x = x.norm()
109
110
111 var min, max int
112 for i, b := range x {
113 if i == 0 || b < min {
114 min = b
115 }
116 if i == 0 || b > max {
117 max = b
118 }
119 }
120 prec0 := uint(max + 1 - min)
121 if prec >= prec0 {
122 return x.Float()
123 }
124
125
126
127 var bit0, rbit, sbit uint
128 var z Bits
129 r := max - int(prec)
130 for _, b := range x {
131 switch {
132 case b == r:
133 rbit = 1
134 case b < r:
135 sbit = 1
136 default:
137
138 if b == r+1 {
139 bit0 = 1
140 }
141 z = append(z, b)
142 }
143 }
144
145
146 f := z.Float()
147 if mode == ToNearestAway {
148 panic("not yet implemented")
149 }
150 if mode == ToNearestEven && rbit == 1 && (sbit == 1 || sbit == 0 && bit0 != 0) || mode == AwayFromZero {
151
152 f.SetMode(ToZero).SetPrec(prec)
153 f.Add(f, Bits{int(r) + 1}.Float())
154 }
155 return f
156 }
157
158
159
160
161 func (bits Bits) Float() *Float {
162
163 if len(bits) == 0 {
164 return new(Float)
165 }
166
167
168
169 var min int
170 for i, b := range bits {
171 if i == 0 || b < min {
172 min = b
173 }
174 }
175
176
177 x := NewInt(0)
178 for _, b := range bits {
179 badj := b - min
180
181 for x.Bit(badj) != 0 {
182 x.SetBit(x, badj, 0)
183 badj++
184 }
185 x.SetBit(x, badj, 1)
186 }
187
188
189 z := new(Float).SetInt(x)
190 if e := int64(z.exp) + int64(min); MinExp <= e && e <= MaxExp {
191 z.exp = int32(e)
192 } else {
193
194 panic("exponent out of range")
195 }
196 return z
197 }
198
199 func TestFromBits(t *testing.T) {
200 for _, test := range []struct {
201 bits Bits
202 want string
203 }{
204
205 {nil, "0"},
206 {Bits{0}, "0x.8p+1"},
207 {Bits{1}, "0x.8p+2"},
208 {Bits{-1}, "0x.8p+0"},
209 {Bits{63}, "0x.8p+64"},
210 {Bits{33, -30}, "0x.8000000000000001p+34"},
211 {Bits{255, 0}, "0x.8000000000000000000000000000000000000000000000000000000000000001p+256"},
212
213
214 {Bits{0, 0}, "0x.8p+2"},
215 {Bits{0, 0, 0, 0}, "0x.8p+3"},
216 {Bits{0, 1, 0}, "0x.8p+3"},
217 {append(Bits{2, 1, 0} , Bits{3, 1} ...), "0x.88p+5" },
218 } {
219 f := test.bits.Float()
220 if got := f.Text('p', 0); got != test.want {
221 t.Errorf("setBits(%v) = %s; want %s", test.bits, got, test.want)
222 }
223 }
224 }
225
View as plain text