v2 / vlib / math / unsigned / uint128_test.v
254 lines · 237 sloc · 6.41 KB · ee9eefd81b028a81920d2965fee52311a1c94d3b
Raw
1import math.big
2import math.unsigned
3import rand
4
5fn test_str() {
6 x := unsigned.uint128_from_dec_str('170141183460469231713240559642174554112') or { panic('') }
7 assert x.str() == '170141183460469231713240559642174554112'
8 y := unsigned.uint128_from_64(42)
9 assert y.str() == '42'
10}
11
12fn test_ops() {
13 x := unsigned.uint128_from_64(18446744073709551615)
14 y := unsigned.uint128_from_64(18446744073709551615)
15 z := unsigned.uint128_from_dec_str('340282366920938463426481119284349108225') or {
16 assert false
17 panic('')
18 }
19 assert (x * y).str() == '340282366920938463426481119284349108225'
20 assert (x + y).str() == '36893488147419103230'
21 assert (z / unsigned.uint128_from_64(2)).str() == '170141183460469231713240559642174554112'
22 assert (unsigned.uint128_from_dec_str('170141183460469231713240559642174554112') or {
23 panic('')
24 } - unsigned.uint128_from_64(2)).str() == '170141183460469231713240559642174554110'
25
26 assert x == y
27 assert unsigned.uint128_from_dec_str('340282366920938463426481119284349108225') or {
28 assert false
29 panic('')
30 } > y
31}
32
33struct LeadingZeros {
34 l unsigned.Uint128
35 r unsigned.Uint128
36 zeros int
37}
38
39fn new(x u64, y u64) unsigned.Uint128 {
40 return unsigned.Uint128{x, y}
41}
42
43fn test_leading_zeros() {
44 tcs := [
45 LeadingZeros{
46 l: new(0x00, 0xf000000000000000)
47 r: new(0x00, 0x8000000000000000)
48 zeros: 1
49 },
50 LeadingZeros{
51 l: new(0x00, 0xf000000000000000)
52 r: new(0x00, 0xc000000000000000)
53 zeros: 2
54 },
55 LeadingZeros{
56 l: new(0x00, 0xf000000000000000)
57 r: new(0x00, 0xe000000000000000)
58 zeros: 3
59 },
60 LeadingZeros{
61 l: new(0x00, 0xffff000000000000)
62 r: new(0x00, 0xff00000000000000)
63 zeros: 8
64 },
65 LeadingZeros{
66 l: new(0x00, 0x000000000000ffff)
67 r: new(0x00, 0x000000000000ff00)
68 zeros: 56
69 },
70 LeadingZeros{
71 l: new(0xf000000000000000, 0x01)
72 r: new(0x4000000000000000, 0x00)
73 zeros: 63
74 },
75 LeadingZeros{
76 l: new(0xf000000000000000, 0x00)
77 r: new(0x4000000000000000, 0x00)
78 zeros: 64
79 },
80 LeadingZeros{
81 l: new(0xf000000000000000, 0x00)
82 r: new(0x8000000000000000, 0x00)
83 zeros: 65
84 },
85 LeadingZeros{
86 l: new(0x00, 0x00)
87 r: new(0x00, 0x00)
88 zeros: 128
89 },
90 LeadingZeros{
91 l: new(0x01, 0x00)
92 r: new(0x00, 0x00)
93 zeros: 127
94 },
95 ]
96
97 for tc in tcs {
98 zeros := tc.l.xor(tc.r).leading_zeros()
99 assert zeros == tc.zeros
100 }
101}
102
103fn test_separators() {
104 // numbers of varying lengths and a random
105 // scattering of '_' throughout.
106 test_strings := [
107 '_',
108 '__',
109 '_0',
110 '0_',
111 '_0_',
112 '_1',
113 '1_',
114 '_1_',
115 '1_2',
116 '_12',
117 '12_',
118 '12_3',
119 '1_23_4',
120 '12_345',
121 '_123_456_',
122 '1_234_567',
123 '1234_5678',
124 '_123456789',
125 '1234567890_',
126 '0_123_456_789_0',
127 '90_12_345_67890',
128 '8901_234_567890_',
129 '_7890_123456789_0',
130 '678901234_567890',
131 '567890_1234567890',
132 '4567890123__4567890',
133 '_34567890123_4567890',
134 '2345678_90123_4567890',
135 '123456789_01_234567890',
136 '01234567_8901234567890',
137 '9012345678901_234567890__',
138 '8_90123456_78901234567890',
139 '78901234567890_123_4567890',
140 '___67890123_4_5_6_78901234567890___',
141 '567890123_45678901234567890',
142 '45_67890123456789_01234567890',
143 '3456789012_345678901234567890',
144 '234_567890_1234_5__67890_1234567890_',
145 '12345678_90123_456789_0123_4567890',
146 '0_123_456_789_012_345_678_901_234_567_890',
147 '90_123456__78901__234567_8901_234567890',
148 '890123456789012345678901234567_890',
149 '7890_1234567_8901234567890_1234567890',
150 '67890123_45678_901234567_8901234567890',
151 '567890_1234567890_12345678901_234567890',
152 '45678_9012345_6789012345678901234567890_',
153 '34567890123456_789012345678901234567890',
154 '234567_890_1234567890_1234567890_1234567890',
155 '334567890_1234567890_1234567890_1234567890',
156 '340282360_0000000000_0000000000_0000000000',
157 '340282366_9209384634_2648111928_4349108225',
158 '340282366_9209384634_6337460743_1768211455',
159 ]
160
161 for ts in test_strings {
162 with := unsigned.uint128_from_dec_str(ts) or {
163 assert false, 'invalid Uint128 string ${ts}'
164 panic('')
165 }
166
167 without := unsigned.uint128_from_dec_str(ts.replace('_', '')) or {
168 assert false, 'invalid Uint128 string ${ts.replace('_', '')}'
169 panic('')
170 }
171
172 assert with == without
173 }
174}
175
176fn test_new() {
177 assert unsigned.uint128_new(max_u64, max_u64) == unsigned.uint128_max
178}
179
180fn test_lsh() {
181 a := unsigned.uint128_from_dec_str('123456789012345678901234567890')!
182 assert a.str() == a.lsh(0).str()
183 assert '246913578024691357802469135780' == a.lsh(1).str()
184 assert '259801135457060040952792416454273138688' == a.lsh(64).str()
185 assert '302984417681386893975453667670529933312' == a.lsh(100).str()
186 assert unsigned.uint128_zero == a.lsh(200)
187}
188
189fn test_rsh() {
190 a := unsigned.uint128_from_dec_str('279625844435276397900870454226348864638')!
191 assert a.str() == a.rsh(0).str()
192 assert '139812922217638198950435227113174432319' == a.rsh(1).str()
193 assert '15158547400991018568' == a.rsh(64).str()
194 assert '220585896' == a.rsh(100).str()
195 assert '1' == a.rsh(127).str()
196 assert unsigned.uint128_zero == a.rsh(200)
197}
198
199fn test_quo_rem() {
200 for a_lo in 0 .. 16 {
201 for a_hi in 0 .. 16 {
202 for b_lo in 0 .. 16 {
203 for b_hi in 0 .. 16 {
204 a := unsigned.uint128_new(u64(1 << a_lo), u64(1 << a_hi))
205 b := unsigned.uint128_new(u64(1 << b_lo), u64(1 << b_hi))
206 big_a := big.integer_from_string(a.str())!
207 big_b := big.integer_from_string(b.str())!
208 q, r := a.quo_rem(b)
209 big_q, big_r := big_a.div_mod(big_b)
210 assert q.str() == big_q.str()
211 assert r.str() == big_r.str()
212 }
213 }
214 }
215 }
216}
217
218fn test_div_128() {
219 for a_lo in 0 .. 4 {
220 for a_hi in 0 .. 4 {
221 for b_lo in 0 .. 4 {
222 for b_hi in 0 .. 4 {
223 for c_lo in 0 .. 4 {
224 for c_hi in 0 .. 4 {
225 a := unsigned.uint128_new(u64(1 << a_lo), u64(1 << a_hi))
226 b := unsigned.uint128_new(u64(1 << b_lo), u64(1 << b_hi))
227 c := unsigned.uint128_new(u64(1 << c_lo), u64(1 << c_hi))
228 if c.cmp(a) <= 0 {
229 continue
230 }
231 aa := unsigned.uint256_new(b, a)
232 big_a := big.integer_from_string(aa.str())!
233 big_b := big.integer_from_string(c.str())!
234 q, r := unsigned.div_128(a, b, c)
235 big_q, big_r := big_a.div_mod(big_b)
236 assert q.str() == big_q.str()
237 assert r.str() == big_r.str()
238 }
239 }
240 }
241 }
242 }
243 }
244}
245
246fn test_put_bytes() {
247 a := unsigned.uint128_new(rand.u64(), rand.u64())
248 b := a.reverse_bytes()
249 mut buf_a := []u8{len: 16}
250 mut buf_b := []u8{len: 16}
251 a.put_bytes(mut buf_a)
252 b.put_bytes(mut buf_b)
253 assert buf_a == buf_b.reverse()
254}
255