Commit | Line | Data |
0716bf9b |
1 | #!/usr/bin/perl -w |
2 | |
3 | use strict; |
4 | use Test; |
5 | |
6 | BEGIN |
7 | { |
8 | $| = 1; |
027dc388 |
9 | chdir 't' if -d 't'; |
56d9de68 |
10 | unshift @INC, '../lib'; # for running manually |
61f5c3f5 |
11 | } |
12 | |
13 | use Math::BigInt::Calc; |
14 | |
15 | BEGIN |
16 | { |
990fb837 |
17 | plan tests => 258; |
0716bf9b |
18 | } |
19 | |
56d9de68 |
20 | # testing of Math::BigInt::Calc |
0716bf9b |
21 | |
56d9de68 |
22 | my $C = 'Math::BigInt::Calc'; # pass classname to sub's |
574bacfe |
23 | |
0716bf9b |
24 | # _new and _str |
bd05a461 |
25 | my $x = $C->_new(\"123"); my $y = $C->_new(\"321"); |
26 | ok (ref($x),'ARRAY'); ok (${$C->_str($x)},123); ok (${$C->_str($y)},321); |
0716bf9b |
27 | |
61f5c3f5 |
28 | ############################################################################### |
0716bf9b |
29 | # _add, _sub, _mul, _div |
bd05a461 |
30 | ok (${$C->_str($C->_add($x,$y))},444); |
31 | ok (${$C->_str($C->_sub($x,$y))},123); |
32 | ok (${$C->_str($C->_mul($x,$y))},39483); |
33 | ok (${$C->_str($C->_div($x,$y))},123); |
0716bf9b |
34 | |
61f5c3f5 |
35 | ############################################################################### |
36 | # check that mul/div doesn't change $y |
37 | # and returns the same reference, not something new |
bd05a461 |
38 | ok (${$C->_str($C->_mul($x,$y))},39483); |
61f5c3f5 |
39 | ok (${$C->_str($x)},39483); ok (${$C->_str($y)},321); |
40 | |
41 | ok (${$C->_str($C->_div($x,$y))},123); |
42 | ok (${$C->_str($x)},123); ok (${$C->_str($y)},321); |
43 | |
44 | $x = $C->_new(\"39483"); |
45 | my ($x1,$r1) = $C->_div($x,$y); |
46 | ok ("$x1","$x"); |
47 | $C->_inc($x1); |
48 | ok ("$x1","$x"); |
49 | ok (${$C->_str($r1)},'0'); |
50 | |
51 | $x = $C->_new(\"39483"); # reset |
52 | |
53 | ############################################################################### |
bd05a461 |
54 | my $z = $C->_new(\"2"); |
55 | ok (${$C->_str($C->_add($x,$z))},39485); |
56 | my ($re,$rr) = $C->_div($x,$y); |
0716bf9b |
57 | |
bd05a461 |
58 | ok (${$C->_str($re)},123); ok (${$C->_str($rr)},2); |
0716bf9b |
59 | |
60 | # is_zero, _is_one, _one, _zero |
56d9de68 |
61 | ok ($C->_is_zero($x)||0,0); |
62 | ok ($C->_is_one($x)||0,0); |
0716bf9b |
63 | |
56d9de68 |
64 | ok (${$C->_str($C->_zero())},"0"); |
65 | ok (${$C->_str($C->_one())},"1"); |
66 | |
67 | # _two() (only used internally) |
68 | ok (${$C->_str($C->_two())},"2"); |
69 | |
70 | ok ($C->_is_one($C->_one()),1); |
71 | |
72 | ok ($C->_is_one($C->_zero()) || 0,0); |
73 | |
74 | ok ($C->_is_zero($C->_zero()),1); |
75 | |
76 | ok ($C->_is_zero($C->_one()) || 0,0); |
574bacfe |
77 | |
78 | # is_odd, is_even |
56d9de68 |
79 | ok ($C->_is_odd($C->_one()),1); ok ($C->_is_odd($C->_zero())||0,0); |
80 | ok ($C->_is_even($C->_one()) || 0,0); ok ($C->_is_even($C->_zero()),1); |
81 | |
82 | # _len |
83 | $x = $C->_new(\"1"); ok ($C->_len($x),1); |
84 | $x = $C->_new(\"12"); ok ($C->_len($x),2); |
85 | $x = $C->_new(\"123"); ok ($C->_len($x),3); |
86 | $x = $C->_new(\"1234"); ok ($C->_len($x),4); |
87 | $x = $C->_new(\"12345"); ok ($C->_len($x),5); |
88 | $x = $C->_new(\"123456"); ok ($C->_len($x),6); |
89 | $x = $C->_new(\"1234567"); ok ($C->_len($x),7); |
90 | $x = $C->_new(\"12345678"); ok ($C->_len($x),8); |
91 | $x = $C->_new(\"123456789"); ok ($C->_len($x),9); |
92 | |
93 | $x = $C->_new(\"8"); ok ($C->_len($x),1); |
94 | $x = $C->_new(\"21"); ok ($C->_len($x),2); |
95 | $x = $C->_new(\"321"); ok ($C->_len($x),3); |
96 | $x = $C->_new(\"4321"); ok ($C->_len($x),4); |
97 | $x = $C->_new(\"54321"); ok ($C->_len($x),5); |
98 | $x = $C->_new(\"654321"); ok ($C->_len($x),6); |
99 | $x = $C->_new(\"7654321"); ok ($C->_len($x),7); |
100 | $x = $C->_new(\"87654321"); ok ($C->_len($x),8); |
101 | $x = $C->_new(\"987654321"); ok ($C->_len($x),9); |
102 | |
103 | for (my $i = 1; $i < 9; $i++) |
104 | { |
105 | my $a = "$i" . '0' x ($i-1); |
106 | $x = $C->_new(\$a); |
107 | print "# Tried len '$a'\n" unless ok ($C->_len($x),$i); |
108 | } |
0716bf9b |
109 | |
574bacfe |
110 | # _digit |
bd05a461 |
111 | $x = $C->_new(\"123456789"); |
112 | ok ($C->_digit($x,0),9); |
113 | ok ($C->_digit($x,1),8); |
114 | ok ($C->_digit($x,2),7); |
115 | ok ($C->_digit($x,-1),1); |
116 | ok ($C->_digit($x,-2),2); |
117 | ok ($C->_digit($x,-3),3); |
574bacfe |
118 | |
119 | # _copy |
56d9de68 |
120 | foreach (qw/ 1 12 123 1234 12345 123456 1234567 12345678 123456789/) |
121 | { |
122 | $x = $C->_new(\"$_"); |
123 | ok (${$C->_str($C->_copy($x))},"$_"); |
124 | ok (${$C->_str($x)},"$_"); # did _copy destroy original x? |
125 | } |
574bacfe |
126 | |
127 | # _zeros |
bd05a461 |
128 | $x = $C->_new(\"1256000000"); ok ($C->_zeros($x),6); |
129 | $x = $C->_new(\"152"); ok ($C->_zeros($x),0); |
130 | $x = $C->_new(\"123000"); ok ($C->_zeros($x),3); |
574bacfe |
131 | |
132 | # _lsft, _rsft |
bd05a461 |
133 | $x = $C->_new(\"10"); $y = $C->_new(\"3"); |
134 | ok (${$C->_str($C->_lsft($x,$y,10))},10000); |
135 | $x = $C->_new(\"20"); $y = $C->_new(\"3"); |
136 | ok (${$C->_str($C->_lsft($x,$y,10))},20000); |
61f5c3f5 |
137 | |
bd05a461 |
138 | $x = $C->_new(\"128"); $y = $C->_new(\"4"); |
61f5c3f5 |
139 | ok (${$C->_str($C->_lsft($x,$y,2))}, 128 << 4); |
140 | |
bd05a461 |
141 | $x = $C->_new(\"1000"); $y = $C->_new(\"3"); |
142 | ok (${$C->_str($C->_rsft($x,$y,10))},1); |
143 | $x = $C->_new(\"20000"); $y = $C->_new(\"3"); |
144 | ok (${$C->_str($C->_rsft($x,$y,10))},20); |
145 | $x = $C->_new(\"256"); $y = $C->_new(\"4"); |
61f5c3f5 |
146 | ok (${$C->_str($C->_rsft($x,$y,2))},256 >> 4); |
0716bf9b |
147 | |
56d9de68 |
148 | $x = $C->_new(\"6411906467305339182857313397200584952398"); |
149 | $y = $C->_new(\"45"); |
150 | ok (${$C->_str($C->_rsft($x,$y,10))},0); |
151 | |
574bacfe |
152 | # _acmp |
bd05a461 |
153 | $x = $C->_new(\"123456789"); |
154 | $y = $C->_new(\"987654321"); |
155 | ok ($C->_acmp($x,$y),-1); |
156 | ok ($C->_acmp($y,$x),1); |
157 | ok ($C->_acmp($x,$x),0); |
158 | ok ($C->_acmp($y,$y),0); |
574bacfe |
159 | |
56d9de68 |
160 | $x = $C->_new(\"1234567890123456789"); |
161 | $y = $C->_new(\"987654321012345678"); |
162 | ok ($C->_acmp($x,$y),1); |
163 | ok ($C->_acmp($y,$x),-1); |
164 | ok ($C->_acmp($x,$x),0); |
165 | ok ($C->_acmp($y,$y),0); |
166 | |
167 | $x = $C->_new(\"1234"); |
168 | $y = $C->_new(\"987654321012345678"); |
169 | ok ($C->_acmp($x,$y),-1); |
170 | ok ($C->_acmp($y,$x),1); |
171 | ok ($C->_acmp($x,$x),0); |
172 | ok ($C->_acmp($y,$y),0); |
173 | |
174 | # _modinv |
175 | $x = $C->_new(\"8"); |
176 | $y = $C->_new(\"5033"); |
177 | my ($xmod,$sign) = $C->_modinv($x,$y); |
178 | ok (${$C->_str($xmod)},'629'); # -629 % 5033 == 4404 |
179 | ok ($sign, '-'); |
180 | |
574bacfe |
181 | # _div |
bd05a461 |
182 | $x = $C->_new(\"3333"); $y = $C->_new(\"1111"); |
183 | ok (${$C->_str(scalar $C->_div($x,$y))},3); |
184 | $x = $C->_new(\"33333"); $y = $C->_new(\"1111"); ($x,$y) = $C->_div($x,$y); |
185 | ok (${$C->_str($x)},30); ok (${$C->_str($y)},3); |
186 | $x = $C->_new(\"123"); $y = $C->_new(\"1111"); |
187 | ($x,$y) = $C->_div($x,$y); ok (${$C->_str($x)},0); ok (${$C->_str($y)},123); |
574bacfe |
188 | |
189 | # _num |
56d9de68 |
190 | foreach (qw/1 12 123 1234 12345 1234567 12345678 123456789 1234567890/) |
191 | { |
192 | $x = $C->_new(\"$_"); |
193 | ok (ref($x)||'','ARRAY'); ok (${$C->_str($x)},"$_"); |
194 | $x = $C->_num($x); ok (ref($x)||'',''); ok ($x,$_); |
195 | } |
574bacfe |
196 | |
b3abae2a |
197 | # _sqrt |
198 | $x = $C->_new(\"144"); ok (${$C->_str($C->_sqrt($x))},'12'); |
990fb837 |
199 | $x = $C->_new(\"144000000000000"); ok (${$C->_str($C->_sqrt($x))},'12000000'); |
200 | |
201 | # _root |
202 | $x = $C->_new(\"81"); my $n = $C->_new(\"3"); # 4*4*4 = 64, 5*5*5 = 125 |
203 | ok (${$C->_str($C->_root($x,$n))},'4'); # 4.xx => 4.0 |
204 | $x = $C->_new(\"81"); $n = $C->_new(\"4"); # 3*3*3*3 == 81 |
205 | ok (${$C->_str($C->_root($x,$n))},'3'); |
b3abae2a |
206 | |
207 | # _fac |
208 | $x = $C->_new(\"0"); ok (${$C->_str($C->_fac($x))},'1'); |
209 | $x = $C->_new(\"1"); ok (${$C->_str($C->_fac($x))},'1'); |
210 | $x = $C->_new(\"2"); ok (${$C->_str($C->_fac($x))},'2'); |
211 | $x = $C->_new(\"3"); ok (${$C->_str($C->_fac($x))},'6'); |
212 | $x = $C->_new(\"4"); ok (${$C->_str($C->_fac($x))},'24'); |
213 | $x = $C->_new(\"5"); ok (${$C->_str($C->_fac($x))},'120'); |
214 | $x = $C->_new(\"10"); ok (${$C->_str($C->_fac($x))},'3628800'); |
215 | $x = $C->_new(\"11"); ok (${$C->_str($C->_fac($x))},'39916800'); |
56d9de68 |
216 | $x = $C->_new(\"12"); ok (${$C->_str($C->_fac($x))},'479001600'); |
217 | |
218 | ############################################################################## |
219 | # _inc and _dec |
220 | foreach (qw/1 11 121 1231 12341 1234561 12345671 123456781 1234567891/) |
221 | { |
222 | $x = $C->_new(\"$_"); $C->_inc($x); |
223 | print "# \$x = ",${$C->_str($x)},"\n" |
224 | unless ok (${$C->_str($x)},substr($_,0,length($_)-1) . '2'); |
225 | $C->_dec($x); ok (${$C->_str($x)},$_); |
226 | } |
227 | foreach (qw/19 119 1219 12319 1234519 12345619 123456719 1234567819/) |
228 | { |
229 | $x = $C->_new(\"$_"); $C->_inc($x); |
230 | print "# \$x = ",${$C->_str($x)},"\n" |
231 | unless ok (${$C->_str($x)},substr($_,0,length($_)-2) . '20'); |
232 | $C->_dec($x); ok (${$C->_str($x)},$_); |
233 | } |
234 | foreach (qw/999 9999 99999 9999999 99999999 999999999 9999999999 99999999999/) |
235 | { |
236 | $x = $C->_new(\"$_"); $C->_inc($x); |
237 | print "# \$x = ",${$C->_str($x)},"\n" |
238 | unless ok (${$C->_str($x)}, '1' . '0' x (length($_))); |
239 | $C->_dec($x); ok (${$C->_str($x)},$_); |
240 | } |
b3abae2a |
241 | |
e745a66c |
242 | $x = $C->_new(\"1000"); $C->_inc($x); ok (${$C->_str($x)},'1001'); |
243 | $C->_dec($x); ok (${$C->_str($x)},'1000'); |
244 | |
56d9de68 |
245 | my $BL; |
246 | { |
247 | no strict 'refs'; |
248 | $BL = &{"$C"."::_base_len"}(); |
249 | } |
250 | |
e745a66c |
251 | $x = '1' . '0' x $BL; |
252 | $z = '1' . '0' x ($BL-1); $z .= '1'; |
253 | $x = $C->_new(\$x); $C->_inc($x); ok (${$C->_str($x)},$z); |
254 | |
255 | $x = '1' . '0' x $BL; $z = '9' x $BL; |
256 | $x = $C->_new(\$x); $C->_dec($x); ok (${$C->_str($x)},$z); |
257 | |
574bacfe |
258 | # should not happen: |
bd05a461 |
259 | # $x = $C->_new(\"-2"); $y = $C->_new(\"4"); ok ($C->_acmp($x,$y),-1); |
574bacfe |
260 | |
56d9de68 |
261 | ############################################################################### |
394e6ffb |
262 | # _mod |
263 | $x = $C->_new(\"1000"); $y = $C->_new(\"3"); |
264 | ok (${$C->_str(scalar $C->_mod($x,$y))},1); |
265 | $x = $C->_new(\"1000"); $y = $C->_new(\"2"); |
266 | ok (${$C->_str(scalar $C->_mod($x,$y))},0); |
267 | |
268 | # _and, _or, _xor |
269 | $x = $C->_new(\"5"); $y = $C->_new(\"2"); |
270 | ok (${$C->_str(scalar $C->_xor($x,$y))},7); |
271 | $x = $C->_new(\"5"); $y = $C->_new(\"2"); |
272 | ok (${$C->_str(scalar $C->_or($x,$y))},7); |
273 | $x = $C->_new(\"5"); $y = $C->_new(\"3"); |
274 | ok (${$C->_str(scalar $C->_and($x,$y))},1); |
275 | |
276 | # _from_hex, _from_bin |
277 | ok (${$C->_str(scalar $C->_from_hex(\"0xFf"))},255); |
278 | ok (${$C->_str(scalar $C->_from_bin(\"0b10101011"))},160+11); |
279 | |
61f5c3f5 |
280 | # _as_hex, _as_bin |
281 | ok (${$C->_str(scalar $C->_from_hex( $C->_as_hex( $C->_new(\"128"))))}, 128); |
282 | ok (${$C->_str(scalar $C->_from_bin( $C->_as_bin( $C->_new(\"128"))))}, 128); |
990fb837 |
283 | ok (${$C->_str(scalar $C->_from_hex( $C->_as_hex( $C->_new(\"0"))))}, 0); |
284 | ok (${$C->_str(scalar $C->_from_bin( $C->_as_bin( $C->_new(\"0"))))}, 0); |
285 | ok ( ${$C->_as_hex( $C->_new(\"0"))}, '0x0'); |
286 | ok ( ${$C->_as_bin( $C->_new(\"0"))}, '0b0'); |
287 | ok ( ${$C->_as_hex( $C->_new(\"12"))}, '0xc'); |
288 | ok ( ${$C->_as_bin( $C->_new(\"12"))}, '0b1100'); |
61f5c3f5 |
289 | |
574bacfe |
290 | # _check |
bd05a461 |
291 | $x = $C->_new(\"123456789"); |
292 | ok ($C->_check($x),0); |
293 | ok ($C->_check(123),'123 is not a reference'); |
0716bf9b |
294 | |
61f5c3f5 |
295 | ############################################################################### |
56d9de68 |
296 | # __strip_zeros |
297 | |
298 | { |
299 | no strict 'refs'; |
300 | # correct empty arrays |
301 | $x = &{$C."::__strip_zeros"}([]); ok (@$x,1); ok ($x->[0],0); |
302 | # don't strip single elements |
303 | $x = &{$C."::__strip_zeros"}([0]); ok (@$x,1); ok ($x->[0],0); |
304 | $x = &{$C."::__strip_zeros"}([1]); ok (@$x,1); ok ($x->[0],1); |
305 | # don't strip non-zero elements |
306 | $x = &{$C."::__strip_zeros"}([0,1]); |
307 | ok (@$x,2); ok ($x->[0],0); ok ($x->[1],1); |
308 | $x = &{$C."::__strip_zeros"}([0,1,2]); |
309 | ok (@$x,3); ok ($x->[0],0); ok ($x->[1],1); ok ($x->[2],2); |
310 | |
311 | # but strip leading zeros |
312 | $x = &{$C."::__strip_zeros"}([0,1,2,0]); |
313 | ok (@$x,3); ok ($x->[0],0); ok ($x->[1],1); ok ($x->[2],2); |
314 | |
315 | $x = &{$C."::__strip_zeros"}([0,1,2,0,0]); |
316 | ok (@$x,3); ok ($x->[0],0); ok ($x->[1],1); ok ($x->[2],2); |
317 | |
318 | $x = &{$C."::__strip_zeros"}([0,1,2,0,0,0]); |
319 | ok (@$x,3); ok ($x->[0],0); ok ($x->[1],1); ok ($x->[2],2); |
320 | |
321 | # collapse multiple zeros |
322 | $x = &{$C."::__strip_zeros"}([0,0,0,0]); |
323 | ok (@$x,1); ok ($x->[0],0); |
324 | } |
61f5c3f5 |
325 | |
0716bf9b |
326 | # done |
327 | |
328 | 1; |
574bacfe |
329 | |