1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
9 var cmpTests
= []struct {
21 {nat
{0, _M
}, nat
{1}, 1},
22 {nat
{1}, nat
{0, _M
}, -1},
23 {nat
{1, _M
}, nat
{0, _M
}, 1},
24 {nat
{0, _M
}, nat
{1, _M
}, -1},
25 {nat
{16, 571956, 8794, 68}, nat
{837, 9146, 1, 754489}, -1},
26 {nat
{34986, 41, 105, 1957}, nat
{56, 7458, 104, 1957}, 1},
30 func TestCmp(t
*testing
.T
) {
31 for i
, a
:= range cmpTests
{
34 t
.Errorf("#%d got r = %v; want %v", i
, r
, a
.r
)
40 type funNN
func(z
, x
, y nat
) nat
48 {nat
{1}, nil, nat
{1}},
49 {nat
{1111111110}, nat
{123456789}, nat
{987654321}},
50 {nat
{0, 0, 0, 1}, nil, nat
{0, 0, 0, 1}},
51 {nat
{0, 0, 0, 1111111110}, nat
{0, 0, 0, 123456789}, nat
{0, 0, 0, 987654321}},
52 {nat
{0, 0, 0, 1}, nat
{0, 0, _M
}, nat
{0, 0, 1}},
60 {nat
{991}, nat
{991}, nat
{1}},
61 {nat
{991 * 991}, nat
{991}, nat
{991}},
62 {nat
{0, 0, 991 * 991}, nat
{0, 991}, nat
{0, 991}},
63 {nat
{1 * 991, 2 * 991, 3 * 991, 4 * 991}, nat
{1, 2, 3, 4}, nat
{991}},
64 {nat
{4, 11, 20, 30, 20, 11, 4}, nat
{1, 2, 3, 4}, nat
{4, 3, 2, 1}},
68 func TestSet(t
*testing
.T
) {
69 for _
, a
:= range sumNN
{
70 z
:= nat(nil).set(a
.z
)
72 t
.Errorf("got z = %v; want %v", z
, a
.z
)
78 func testFunNN(t
*testing
.T
, msg
string, f funNN
, a argNN
) {
81 t
.Errorf("%s%+v\n\tgot z = %v; want %v", msg
, a
, z
, a
.z
)
86 func TestFunNN(t
*testing
.T
) {
87 for _
, a
:= range sumNN
{
89 testFunNN(t
, "add", nat
.add
, arg
)
91 arg
= argNN
{a
.z
, a
.y
, a
.x
}
92 testFunNN(t
, "add symmetric", nat
.add
, arg
)
94 arg
= argNN
{a
.x
, a
.z
, a
.y
}
95 testFunNN(t
, "sub", nat
.sub
, arg
)
97 arg
= argNN
{a
.y
, a
.z
, a
.x
}
98 testFunNN(t
, "sub symmetric", nat
.sub
, arg
)
101 for _
, a
:= range prodNN
{
103 testFunNN(t
, "mul", nat
.mul
, arg
)
105 arg
= argNN
{a
.z
, a
.y
, a
.x
}
106 testFunNN(t
, "mul symmetric", nat
.mul
, arg
)
111 var mulRangesN
= []struct {
122 {1, 0, "1"}, // empty range
123 {100, 1, "1"}, // empty range
124 {1, 10, "3628800"}, // 10!
125 {1, 20, "2432902008176640000"}, // 20!
127 "933262154439441526816992388562667004907159682643816214685929" +
128 "638952175999932299156089414639761565182862536979208272237582" +
129 "51185210916864000000000000000000000000", // 100!
134 func TestMulRangeN(t
*testing
.T
) {
135 for i
, r
:= range mulRangesN
{
136 prod
:= nat(nil).mulRange(r
.a
, r
.b
).string(10)
138 t
.Errorf("#%d: got %s; want %s", i
, prod
, r
.prod
)
144 var mulArg
, mulTmp nat
148 mulArg
= make(nat
, n
)
149 for i
:= 0; i
< n
; i
++ {
155 func benchmarkMulLoad() {
156 for j
:= 1; j
<= 10; j
++ {
157 x
:= mulArg
[0 : j
*100]
163 func BenchmarkMul(b
*testing
.B
) {
164 for i
:= 0; i
< b
.N
; i
++ {
178 {nat
{1234567890}, 10, "1234567890"},
182 func TestString(t
*testing
.T
) {
183 for _
, a
:= range tab
{
186 t
.Errorf("string%+v\n\tgot s = %s; want %s", a
, s
, a
.s
)
189 x
, b
, n
:= nat(nil).scan(a
.s
, a
.b
)
191 t
.Errorf("scan%+v\n\tgot z = %v; want %v", a
, x
, a
.x
)
194 t
.Errorf("scan%+v\n\tgot b = %d; want %d", a
, b
, a
.b
)
197 t
.Errorf("scan%+v\n\tgot n = %d; want %d", a
, n
, len(a
.s
))
203 func TestLeadingZeros(t
*testing
.T
) {
205 for i
:= 0; i
<= _W
; i
++ {
206 if int(leadingZeros(x
)) != i
{
207 t
.Errorf("failed at %x: got %d want %d", x
, leadingZeros(x
), i
)
214 type shiftTest
struct {
221 var leftShiftTests
= []shiftTest
{
226 {nat
{1 << (_W
- 1)}, 1, nat
{0}},
227 {nat
{1 << (_W
- 1), 0}, 1, nat
{0, 1}},
231 func TestShiftLeft(t
*testing
.T
) {
232 for i
, test
:= range leftShiftTests
{
234 z
= z
.shl(test
.in
, test
.shift
)
235 for j
, d
:= range test
.out
{
236 if j
>= len(z
) || z
[j
] != d
{
237 t
.Errorf("#%d: got: %v want: %v", i
, z
, test
.out
)
245 var rightShiftTests
= []shiftTest
{
251 {nat
{0, 1}, 1, nat
{1 << (_W
- 1)}},
252 {nat
{2, 1, 1}, 1, nat
{1<<(_W
-1) + 1, 1 << (_W
- 1)}},
256 func TestShiftRight(t
*testing
.T
) {
257 for i
, test
:= range rightShiftTests
{
259 z
= z
.shr(test
.in
, test
.shift
)
260 for j
, d
:= range test
.out
{
261 if j
>= len(z
) || z
[j
] != d
{
262 t
.Errorf("#%d: got: %v want: %v", i
, z
, test
.out
)
270 type modWTest
struct {
277 var modWTests32
= []modWTest
{
278 {"23492635982634928349238759823742", "252341", "220170"},
282 var modWTests64
= []modWTest
{
283 {"6527895462947293856291561095690465243862946", "524326975699234", "375066989628668"},
287 func runModWTests(t
*testing
.T
, tests
[]modWTest
) {
288 for i
, test
:= range tests
{
289 in
, _
:= new(Int
).SetString(test
.in
, 10)
290 d
, _
:= new(Int
).SetString(test
.dividend
, 10)
291 out
, _
:= new(Int
).SetString(test
.out
, 10)
293 r
:= in
.abs
.modW(d
.abs
[0])
295 t
.Errorf("#%d failed: got %s want %s", i
, r
, out
)
301 func TestModW(t
*testing
.T
) {
303 runModWTests(t
, modWTests32
)
306 runModWTests(t
, modWTests64
)
311 func TestTrailingZeroBits(t
*testing
.T
) {
314 for i
:= 0; i
< _W
; i
++ {
315 if trailingZeroBits(x
) != i
{
316 t
.Errorf("Failed at step %d: x: %x got: %d", i
, x
, trailingZeroBits(x
))
323 var expNNTests
= []struct {
327 {"0x8000000000000000", "2", "", "0x40000000000000000000000000000000"},
328 {"0x8000000000000000", "2", "6719", "4944"},
329 {"0x8000000000000000", "3", "6719", "5447"},
330 {"0x8000000000000000", "1000", "6719", "1603"},
331 {"0x8000000000000000", "1000000", "6719", "3199"},
333 "2938462938472983472983659726349017249287491026512746239764525612965293865296239471239874193284792387498274256129746192347",
334 "298472983472983471903246121093472394872319615612417471234712061",
335 "29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
336 "23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
341 func TestExpNN(t
*testing
.T
) {
342 for i
, test
:= range expNNTests
{
343 x
, _
, _
:= nat(nil).scan(test
.x
, 0)
344 y
, _
, _
:= nat(nil).scan(test
.y
, 0)
345 out
, _
, _
:= nat(nil).scan(test
.out
, 0)
350 m
, _
, _
= nat(nil).scan(test
.m
, 0)
353 z
:= nat(nil).expNN(x
, y
, m
)
355 t
.Errorf("#%d got %v want %v", i
, z
, out
)