0b4147c98cd0d19f91c91277ff13d4dde577b58f
[p5sagit/p5-mst-13.2.git] / lib / Math / BigInt / t / bigintpm.inc
1 #include this file into another for subclass testing
2
3 my $version = ${"$class\::VERSION"};
4
5 ##############################################################################
6 # for testing inheritance of _swap
7
8 package Math::Foo;
9
10 use Math::BigInt;
11 #use Math::BigInt lib => 'BitVect';     # for testing
12 use vars qw/@ISA/;
13 @ISA = (qw/Math::BigInt/);
14
15 use overload
16 # customized overload for sub, since original does not use swap there
17 '-'     =>      sub { my @a = ref($_[0])->_swap(@_);
18                    $a[0]->bsub($a[1])};
19
20 sub _swap
21   {
22   # a fake _swap, which reverses the params
23   my $self = shift;                     # for override in subclass
24   if ($_[2])
25     {
26     my $c = ref ($_[0] ) || 'Math::Foo';
27     return ( $_[0]->copy(), $_[1] );
28     }
29   else
30     {
31     return ( Math::Foo->new($_[1]), $_[0] );
32     }
33   }
34
35 ##############################################################################
36 package main;
37
38 my $CALC = $class->_core_lib(); ok ($CALC,'Math::BigInt::Calc');
39
40 my ($f,$z,$a,$exp,@a,$m,$e,$round_mode);
41
42 while (<DATA>) 
43   {
44   chop;
45   next if /^#/; # skip comments
46   if (s/^&//) 
47     {
48     $f = $_;
49     }
50   elsif (/^\$/) 
51     {
52     $round_mode = $_;
53     $round_mode =~ s/^\$/$class\->/;
54     # print "$round_mode\n";
55     }
56   else 
57     {
58     @args = split(/:/,$_,99);
59     $ans = pop(@args);
60     $try = "\$x = $class->new(\"$args[0]\");";
61     if ($f eq "bnorm"){
62       $try = "\$x = $class->bnorm(\"$args[0]\");";
63     } elsif ($f eq "is_zero") {
64       $try .= '$x->is_zero();';
65     } elsif ($f eq "is_one") {
66       $try .= '$x->is_one();';
67     } elsif ($f eq "is_odd") {
68       $try .= '$x->is_odd();';
69     } elsif ($f eq "is_even") {
70       $try .= '$x->is_even();';
71     } elsif ($f eq "is_negative") {
72       $try .= '$x->is_negative();';
73     } elsif ($f eq "is_positive") {
74       $try .= '$x->is_positive();';
75     } elsif ($f eq "as_hex") {
76       $try .= '$x->as_hex();';
77     } elsif ($f eq "as_bin") {
78       $try .= '$x->as_bin();';
79     } elsif ($f eq "is_inf") {
80       $try .= "\$x->is_inf('$args[1]');";
81     } elsif ($f eq "binf") {
82       $try .= "\$x->binf('$args[1]');";
83     } elsif ($f eq "bone") {
84       $try .= "\$x->bone('$args[1]');";
85     } elsif ($f eq "bnan") {
86       $try .= "\$x->bnan();";
87     } elsif ($f eq "bfloor") {
88       $try .= '$x->bfloor();';
89     } elsif ($f eq "bceil") {
90       $try .= '$x->bceil();';
91     } elsif ($f eq "bsstr") {
92       $try .= '$x->bsstr();';
93     } elsif ($f eq "bneg") {
94       $try .= '$x->bneg();';
95     } elsif ($f eq "babs") {
96       $try .= '$x->babs();';
97     } elsif ($f eq "binc") {
98       $try .= '++$x;'; 
99     } elsif ($f eq "bdec") {
100       $try .= '--$x;'; 
101     }elsif ($f eq "bnot") {
102       $try .= '~$x;';
103     }elsif ($f eq "bsqrt") {
104       $try .= '$x->bsqrt();';
105     }elsif ($f eq "length") {
106       $try .= '$x->length();';
107     }elsif ($f eq "exponent"){
108       # ->bstr() to see if an object is returned
109       $try .= '$x = $x->exponent()->bstr();';
110     }elsif ($f eq "mantissa"){
111       # ->bstr() to see if an object is returned
112       $try .= '$x = $x->mantissa()->bstr();';
113     }elsif ($f eq "parts"){
114       $try .= '($m,$e) = $x->parts();'; 
115       # ->bstr() to see if an object is returned
116       $try .= '$m = $m->bstr(); $m = "NaN" if !defined $m;';
117       $try .= '$e = $e->bstr(); $e = "NaN" if !defined $e;';
118       $try .= '"$m,$e";';
119     } else {
120       $try .= "\$y = $class->new('$args[1]');";
121       if ($f eq "bcmp"){
122         $try .= '$x <=> $y;';
123       }elsif ($f eq "bround") {
124       $try .= "$round_mode; \$x->bround(\$y);";
125       }elsif ($f eq "bacmp"){
126         $try .= '$x->bacmp($y);';
127       }elsif ($f eq "badd"){
128         $try .= '$x + $y;';
129       }elsif ($f eq "bsub"){
130         $try .= '$x - $y;';
131       }elsif ($f eq "bmul"){
132         $try .= '$x * $y;';
133       }elsif ($f eq "bdiv"){
134         $try .= '$x / $y;';
135       }elsif ($f eq "bdiv-list"){
136         $try .= 'join (",",$x->bdiv($y));';
137       }elsif ($f eq "bmod"){
138         $try .= '$x % $y;';
139       }elsif ($f eq "bgcd")
140         {
141         if (defined $args[2])
142           {
143           $try .= " \$z = $class->new(\"$args[2]\"); ";
144           }
145         $try .= "$class\::bgcd(\$x, \$y";
146         $try .= ", \$z" if (defined $args[2]);
147         $try .= " );";
148         }
149       elsif ($f eq "blcm")
150         {
151         if (defined $args[2])
152           {
153           $try .= " \$z = $class->new(\"$args[2]\"); ";
154           }
155         $try .= "$class\::blcm(\$x, \$y";
156         $try .= ", \$z" if (defined $args[2]);
157         $try .= " );";
158       }elsif ($f eq "blsft"){
159         if (defined $args[2])
160           {
161           $try .= "\$x->blsft(\$y,$args[2]);";
162           }
163         else
164           {
165           $try .= "\$x << \$y;";
166           }
167       }elsif ($f eq "brsft"){
168         if (defined $args[2])
169           {
170           $try .= "\$x->brsft(\$y,$args[2]);";
171           }
172         else
173           {
174           $try .= "\$x >> \$y;";
175           }
176       }elsif ($f eq "band"){
177         $try .= "\$x & \$y;";
178       }elsif ($f eq "bior"){
179         $try .= "\$x | \$y;";
180       }elsif ($f eq "bxor"){
181         $try .= "\$x ^ \$y;";
182       }elsif ($f eq "bpow"){
183         $try .= "\$x ** \$y;";
184       }elsif ($f eq "digit"){
185         $try = "\$x = $class->new(\"$args[0]\"); \$x->digit($args[1]);";
186       } else { warn "Unknown op '$f'"; }
187     }
188     # print "trying $try\n";
189     $ans1 = eval $try;
190     $ans =~ s/^[+]([0-9])/$1/;          # remove leading '+' 
191     if ($ans eq "")
192       {
193       ok_undef ($ans1); 
194       }
195     else
196       {
197       # print "try: $try ans: $ans1 $ans\n";
198       print "# Tried: '$try'\n" if !ok ($ans1, $ans);
199       }
200     # check internal state of number objects
201     is_valid($ans1,$f) if ref $ans1; 
202     }
203   } # endwhile data tests
204 close DATA;
205
206 # test some more
207 @a = ();
208 for (my $i = 1; $i < 10; $i++) 
209   {
210   push @a, $i;
211   }
212 ok "@a", "1 2 3 4 5 6 7 8 9";
213
214 # test whether self-multiplication works correctly (result is 2**64)
215 $try = "\$x = $class->new('4294967296');";
216 $try .= '$a = $x->bmul($x);';
217 $ans1 = eval $try;
218 print "# Tried: '$try'\n" if !ok ($ans1, $class->new(2) ** 64);
219 # test self-pow
220 $try = "\$x = $class->new(10);";
221 $try .= '$a = $x->bpow($x);';
222 $ans1 = eval $try;
223 print "# Tried: '$try'\n" if !ok ($ans1, $class->new(10) ** 10);
224
225 # test whether op destroys args or not (should better not)
226
227 $x = $class->new(3);
228 $y = $class->new(4);
229 $z = $x & $y;
230 ok ($x,3);
231 ok ($y,4);
232 ok ($z,0);
233 $z = $x | $y;
234 ok ($x,3);
235 ok ($y,4);
236 ok ($z,7);
237 $x = $class->new(1);
238 $y = $class->new(2);
239 $z = $x | $y;
240 ok ($x,1);
241 ok ($y,2);
242 ok ($z,3);
243
244 $x = $class->new(5);
245 $y = $class->new(4);
246 $z = $x ^ $y;
247 ok ($x,5);
248 ok ($y,4);
249 ok ($z,1);
250
251 $x = $class->new(-5); $y = -$x;
252 ok ($x, -5);
253
254 $x = $class->new(-5); $y = abs($x);
255 ok ($x, -5);
256
257 # check whether overloading cmp works
258 $try = "\$x = $class->new(0);";
259 $try .= "\$y = 10;";
260 $try .= "'false' if \$x ne \$y;";
261 $ans = eval $try;
262 print "# For '$try'\n" if (!ok "$ans" , "false" ); 
263
264 # we cant test for working cmpt with other objects here, we would need a dummy
265 # object with stringify overload for this. see Math::String tests as example
266
267 ###############################################################################
268 # check shortcuts
269 $try = "\$x = $class->new(1); \$x += 9;";
270 $try .= "'ok' if \$x == 10;";
271 $ans = eval $try;
272 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
273
274 $try = "\$x = $class->new(1); \$x -= 9;";
275 $try .= "'ok' if \$x == -8;";
276 $ans = eval $try;
277 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
278
279 $try = "\$x = $class->new(1); \$x *= 9;";
280 $try .= "'ok' if \$x == 9;";
281 $ans = eval $try;
282 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
283
284 $try = "\$x = $class->new(10); \$x /= 2;";
285 $try .= "'ok' if \$x == 5;";
286 $ans = eval $try;
287 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
288
289 ###############################################################################
290 # check reversed order of arguments
291 $try = "\$x = $class->new(10); \$x = 2 ** \$x;";
292 $try .= "'ok' if \$x == 1024;"; $ans = eval $try;
293 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
294
295 $try = "\$x = $class->new(10); \$x = 2 * \$x;";
296 $try .= "'ok' if \$x == 20;"; $ans = eval $try;
297 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
298
299 $try = "\$x = $class->new(10); \$x = 2 + \$x;";
300 $try .= "'ok' if \$x == 12;"; $ans = eval $try;
301 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
302
303 $try = "\$x = $class\->new(10); \$x = 2 - \$x;";
304 $try .= "'ok' if \$x == -8;"; $ans = eval $try;
305 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
306
307 $try = "\$x = $class\->new(10); \$x = 20 / \$x;";
308 $try .= "'ok' if \$x == 2;"; $ans = eval $try;
309 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
310
311 ###############################################################################
312 # check badd(4,5) form
313
314 $try = "\$x = $class\->badd(4,5);";
315 $try .= "'ok' if \$x == 9;";
316 $ans = eval $try;
317 print "# For '$try'\n" if (!ok "$ans" , "ok" ); 
318
319 ###############################################################################
320 # check undefs: NOT DONE YET
321
322 ###############################################################################
323 # bool
324
325 $x = Math::BigInt->new(1); if ($x) { ok (1,1); } else { ok($x,'to be true') }
326 $x = Math::BigInt->new(0); if (!$x) { ok (1,1); } else { ok($x,'to be false') }
327
328 ###############################################################################
329 # objectify()
330
331 @args = Math::BigInt::objectify(2,4,5);
332 ok (scalar @args,3);            # $class, 4, 5
333 ok ($args[0],$class);
334 ok ($args[1],4);
335 ok ($args[2],5);
336
337 @args = Math::BigInt::objectify(0,4,5);
338 ok (scalar @args,3);            # $class, 4, 5
339 ok ($args[0],$class);
340 ok ($args[1],4);
341 ok ($args[2],5);
342
343 @args = Math::BigInt::objectify(2,4,5);
344 ok (scalar @args,3);            # $class, 4, 5
345 ok ($args[0],$class);
346 ok ($args[1],4);
347 ok ($args[2],5);
348
349 @args = Math::BigInt::objectify(2,4,5,6,7);
350 ok (scalar @args,5);            # $class, 4, 5, 6, 7
351 ok ($args[0],$class);
352 ok ($args[1],4); ok (ref($args[1]),$args[0]);
353 ok ($args[2],5); ok (ref($args[2]),$args[0]);
354 ok ($args[3],6); ok (ref($args[3]),'');
355 ok ($args[4],7); ok (ref($args[4]),'');
356
357 @args = Math::BigInt::objectify(2,$class,4,5,6,7);
358 ok (scalar @args,5);            # $class, 4, 5, 6, 7
359 ok ($args[0],$class);
360 ok ($args[1],4); ok (ref($args[1]),$args[0]);
361 ok ($args[2],5); ok (ref($args[2]),$args[0]);
362 ok ($args[3],6); ok (ref($args[3]),'');
363 ok ($args[4],7); ok (ref($args[4]),'');
364
365 ###############################################################################
366 # test for floating-point input (other tests in bnorm() below)
367
368 $z = 1050000000000000;          # may be int on systems with 64bit?
369 $x = $class->new($z); ok ($x->bsstr(),'105e+13');       # not 1.05e+15
370 $z = 1e+129;                    # definitely a float (may fail on UTS)
371 # don't compare to $z, since some Perl versions stringify $z into something
372 # like '1.e+129' or something equally ugly
373 $x = $class->new($z); ok ($x->bsstr(),'1e+129');
374
375 ###############################################################################
376 # prime number tests, also test for **= and length()
377 # found on: http://www.utm.edu/research/primes/notes/by_year.html
378
379 # ((2^148)-1)/17
380 $x = $class->new(2); $x **= 148; $x++; $x = $x / 17;
381 ok ($x,"20988936657440586486151264256610222593863921");
382 ok ($x->length(),length "20988936657440586486151264256610222593863921");
383
384 # MM7 = 2^127-1
385 $x = $class->new(2); $x **= 127; $x--;
386 ok ($x,"170141183460469231731687303715884105727");
387
388 $x = $class->new('215960156869840440586892398248');
389 ($x,$y) = $x->length();
390 ok ($x,30); ok ($y,0);
391
392 $x = $class->new('1_000_000_000_000');
393 ($x,$y) = $x->length();
394 ok ($x,13); ok ($y,0);
395
396 # I am afraid the following is not yet possible due to slowness
397 # Also, testing for 2 meg output is a bit hard ;)
398 #$x = $class->new(2); $x **= 6972593; $x--;
399
400 # 593573509*2^332162+1 has exactly 1,000,000 digits
401 # takes about 24 mins on 300 Mhz, so cannot be done yet ;)
402 #$x = $class->new(2); $x **= 332162; $x *= "593573509"; $x++;
403 #ok ($x->length(),1_000_000);
404
405 ###############################################################################
406 # inheritance and overriding of _swap
407
408 $x = Math::Foo->new(5);
409 $x = $x - 8;            # 8 - 5 instead of 5-8
410 ok ($x,3);
411 ok (ref($x),'Math::Foo');
412
413 $x = Math::Foo->new(5);
414 $x = 8 - $x;            # 5 - 8 instead of 8 - 5
415 ok ($x,-3);
416 ok (ref($x),'Math::Foo');
417
418 ###############################################################################
419 # Test whether +inf eq inf
420 # This tried to test whether BigInt inf equals Perl inf. Unfortunately, Perl
421 # hasn't (before 5.7.3 at least) a consistent way to say inf, and some things
422 # like 1e100000 crash on some platforms. So simple test for the string 'inf'
423 $x = $class->new('+inf'); ok ($x,'inf');
424
425 ###############################################################################
426 ###############################################################################
427 # the followin tests only make sense with Math::BigInt::Calc
428
429 exit if $CALC ne 'Math::BigInt::Calc'; # for Pari et al.
430
431 ###############################################################################
432 # check proper length of internal arrays
433
434 my $bl = Math::BigInt::Calc::_base_len();
435 my $BASE = '9' x $bl;
436 my $MAX = $BASE;
437 $BASE++;
438
439 $x = $class->new($MAX); is_valid($x);   # f.i. 9999
440 $x += 1; ok ($x,$BASE); is_valid($x);   # 10000
441 $x -= 1; ok ($x,$MAX); is_valid($x);    # 9999 again
442
443 ###############################################################################
444 # check numify
445
446 $x = $class->new($BASE-1);     ok ($x->numify(),$BASE-1); 
447 $x = $class->new(-($BASE-1));  ok ($x->numify(),-($BASE-1)); 
448 $x = $class->new($BASE);       ok ($x->numify(),$BASE); 
449 $x = $class->new(-$BASE);      ok ($x->numify(),-$BASE);
450 $x = $class->new( -($BASE*$BASE*1+$BASE*1+1) ); 
451 ok($x->numify(),-($BASE*$BASE*1+$BASE*1+1)); 
452
453 ###############################################################################
454 # test bug in _digits with length($c[-1]) where $c[-1] was "00001" instead of 1
455
456 $x = Math::BigInt->new(99998); $x++; $x++; $x++; $x++;
457 if ($x > 100000) { ok (1,1) } else { ok ("$x < 100000","$x > 100000"); }
458
459 $x = Math::BigInt->new(100003); $x++;
460 $y = Math::BigInt->new(1000000);
461 if ($x < 1000000) { ok (1,1) } else { ok ("$x > 1000000","$x < 1000000"); }
462
463 ###############################################################################
464 # bug in sub where number with at least 6 trailing zeros after any op failed
465
466 $x = Math::BigInt->new(123456); $z = Math::BigInt->new(10000); $z *= 10;
467 $x -= $z;
468 ok ($z, 100000);
469 ok ($x, 23456);
470
471 ###############################################################################
472 # bug in shortcut in mul()
473
474 # construct a number with a zero-hole of BASE_LEN
475 $x = '1' x $bl . '0' x $bl . '1' x $bl . '0' x $bl;
476 $y = '1' x (2*$bl);
477 #print "$x * $y\n";
478 $x = Math::BigInt->new($x)->bmul($y);
479 # result is 123..$bl .  $bl x (3*bl-1) . $bl...321 . '0' x $bl
480 $y = ''; my $d = '';
481 for (my $i = 1; $i <= $bl; $i++)
482   {
483   $y .= $i; $d = $i.$d;
484   }
485 #print "$y $d\n";
486 $y .= $bl x (3*$bl-1) . $d . '0' x $bl;
487 ok ($x,$y);
488
489 ###############################################################################
490 # bug with rest "-0" in div, causing further div()s to fail
491
492 $x = Math::BigInt->new('-322056000'); ($x,$y) = $x->bdiv('-12882240');
493
494 ok ($y,'0','not -0');   # not '-0'
495 is_valid($y);
496
497 ### all tests done ############################################################
498
499 1;
500
501 ###############################################################################
502 # Perl 5.005 does not like ok ($x,undef)
503
504 sub ok_undef
505   {
506   my $x = shift;
507
508   ok (1,1) and return if !defined $x;
509   ok ($x,'undef');
510   }
511
512 ###############################################################################
513 # sub to check validity of a BigInt internally, to ensure that no op leaves a
514 # number object in an invalid state (f.i. "-0")
515
516 sub is_valid
517   {
518   my ($x,$f) = @_;
519
520   my $e = 0;                    # error?
521   # ok as reference? 
522   $e = 'Not a reference to Math::BigInt' if !ref($x);
523
524   # has ok sign?
525   $e = "Illegal sign $x->{sign} (expected: '+', '-', '-inf', '+inf' or 'NaN'"
526    if $e eq '0' && $x->{sign} !~ /^(\+|-|\+inf|-inf|NaN)$/;
527
528   $e = "-0 is invalid!" if $e ne '0' && $x->{sign} eq '-' && $x == 0;
529   $e = $CALC->_check($x->{value}) if $e eq '0';
530
531   # test done, see if error did crop up
532   ok (1,1), return if ($e eq '0');
533
534   ok (1,$e." op '$f'");
535   }
536
537 __DATA__
538 &is_negative
539 0:0
540 -1:1
541 1:0
542 +inf:0
543 -inf:1
544 NaNneg:0
545 &is_positive
546 0:1
547 -1:0
548 1:1
549 +inf:1
550 -inf:0
551 NaNneg:0
552 &is_odd
553 abc:0
554 0:0
555 1:1
556 3:1
557 -1:1
558 -3:1
559 10000001:1
560 10000002:0
561 2:0
562 &is_even
563 abc:0
564 0:1
565 1:0
566 3:0
567 -1:0
568 -3:0
569 10000001:0
570 10000002:1
571 2:1
572 &bacmp
573 +0:-0:0
574 +0:+1:-1
575 -1:+1:0
576 +1:-1:0
577 -1:+2:-1
578 +2:-1:1
579 -123456789:+987654321:-1
580 +123456789:-987654321:-1
581 +987654321:+123456789:1
582 -987654321:+123456789:1
583 -123:+4567889:-1
584 # NaNs
585 acmpNaN:123:
586 123:acmpNaN:
587 acmpNaN:acmpNaN:
588 # infinity
589 +inf:+inf:0
590 -inf:-inf:0
591 +inf:-inf:0
592 -inf:+inf:0
593 +inf:123:1
594 -inf:123:1
595 +inf:-123:1
596 -inf:-123:1
597 # return undef
598 +inf:NaN:
599 NaN:inf:
600 -inf:NaN:
601 NaN:-inf:
602 &bnorm
603 123:123
604 # binary input
605 0babc:NaN
606 0b123:NaN
607 0b0:0
608 -0b0:0
609 -0b1:-1
610 0b0001:1
611 0b001:1
612 0b011:3
613 0b101:5
614 0b1000000000000000000000000000000:1073741824
615 0b_101:NaN
616 0b1_0_1:5
617 # hex input
618 -0x0:0
619 0xabcdefgh:NaN
620 0x1234:4660
621 0xabcdef:11259375
622 -0xABCDEF:-11259375
623 -0x1234:-4660
624 0x12345678:305419896
625 0x1_2_3_4_56_78:305419896
626 0x_123:NaN
627 # inf input
628 inf:inf
629 +inf:inf
630 -inf:-inf
631 0inf:NaN
632 # normal input
633 :NaN
634 abc:NaN
635    1 a:NaN
636 1bcd2:NaN
637 11111b:NaN
638 +1z:NaN
639 -1z:NaN
640 0:0
641 +0:0
642 +00:0
643 +000:0
644 000000000000000000:0
645 -0:0
646 -0000:0
647 +1:1
648 +01:1
649 +001:1
650 +00000100000:100000
651 123456789:123456789
652 -1:-1
653 -01:-1
654 -001:-1
655 -123456789:-123456789
656 -00000100000:-100000
657 1_2_3:123
658 _123:NaN
659 _123_:NaN
660 _123_:NaN
661 1__23:NaN
662 10000000000E-1_0:1
663 1E2:100
664 1E1:10
665 1E0:1
666 E1:NaN
667 E23:NaN
668 1.23E2:123
669 1.23E1:NaN
670 1.23E-1:NaN
671 100E-1:10
672 # floating point input
673 1.01E2:101
674 1010E-1:101
675 -1010E0:-1010
676 -1010E1:-10100
677 -1010E-2:NaN
678 -1.01E+1:NaN
679 -1.01E-1:NaN
680 1234.00:1234
681 &bnan
682 1:NaN
683 2:NaN
684 abc:NaN
685 &bone
686 2:+:+1
687 2:-:-1
688 boneNaN:-:-1
689 boneNaN:+:+1
690 2:abc:+1
691 3::+1
692 &binf
693 1:+:inf
694 2:-:-inf
695 3:abc:inf
696 &is_inf
697 +inf::1
698 -inf::1
699 abc::0
700 1::0
701 NaN::0
702 -1::0
703 +inf:-:0
704 +inf:+:1
705 -inf:-:1
706 -inf:+:0
707 # it must be exactly /^[+-]inf$/
708 +infinity::0
709 -infinity::0
710 &blsft
711 abc:abc:NaN
712 +2:+2:+8
713 +1:+32:+4294967296
714 +1:+48:+281474976710656
715 +8:-2:NaN
716 # excercise base 10
717 +12345:4:10:123450000
718 -1234:0:10:-1234
719 +1234:0:10:+1234
720 +2:2:10:200
721 +12:2:10:1200
722 +1234:-3:10:NaN
723 1234567890123:12:10:1234567890123000000000000
724 &brsft
725 abc:abc:NaN
726 +8:+2:+2
727 +4294967296:+32:+1
728 +281474976710656:+48:+1
729 +2:-2:NaN
730 # excercise base 10
731 -1234:0:10:-1234
732 +1234:0:10:+1234
733 +200:2:10:2
734 +1234:3:10:1
735 +1234:2:10:12
736 +1234:-3:10:NaN
737 310000:4:10:31
738 12300000:5:10:123
739 1230000000000:10:10:123
740 09876123456789067890:12:10:9876123
741 1234561234567890123:13:10:123456
742 &bsstr
743 1e+34:1e+34
744 123.456E3:123456e+0
745 100:1e+2
746 abc:NaN
747 &bneg
748 bnegNaN:NaN
749 +inf:-inf
750 -inf:inf
751 abd:NaN
752 +0:+0
753 +1:-1
754 -1:+1
755 +123456789:-123456789
756 -123456789:+123456789
757 &babs
758 babsNaN:NaN
759 +inf:inf
760 -inf:inf
761 +0:+0
762 +1:+1
763 -1:+1
764 +123456789:+123456789
765 -123456789:+123456789
766 &bcmp
767 bcmpNaN:bcmpNaN:
768 bcmpNaN:+0:
769 +0:bcmpNaN:
770 +0:+0:0
771 -1:+0:-1
772 +0:-1:1
773 +1:+0:1
774 +0:+1:-1
775 -1:+1:-1
776 +1:-1:1
777 -1:-1:0
778 +1:+1:0
779 +123:+123:0
780 +123:+12:1
781 +12:+123:-1
782 -123:-123:0
783 -123:-12:-1
784 -12:-123:1
785 +123:+124:-1
786 +124:+123:1
787 -123:-124:1
788 -124:-123:-1
789 +100:+5:1
790 -123456789:+987654321:-1
791 +123456789:-987654321:1
792 -987654321:+123456789:-1
793 -inf:5432112345:-1
794 +inf:5432112345:1
795 -inf:-5432112345:-1
796 +inf:-5432112345:1
797 +inf:+inf:0
798 -inf:-inf:0
799 +inf:-inf:1
800 -inf:+inf:-1
801 5:inf:-1
802 5:inf:-1
803 -5:-inf:1
804 -5:-inf:1
805 # return undef
806 +inf:NaN:
807 NaN:inf:
808 -inf:NaN:
809 NaN:-inf:
810 &binc
811 abc:NaN
812 +inf:inf
813 -inf:-inf
814 +0:+1
815 +1:+2
816 -1:+0
817 &bdec
818 abc:NaN
819 +inf:inf
820 -inf:-inf
821 +0:-1
822 +1:+0
823 -1:-2
824 &badd
825 abc:abc:NaN
826 abc:+0:NaN
827 +0:abc:NaN
828 +inf:-inf:0
829 -inf:+inf:0
830 +inf:+inf:inf
831 -inf:-inf:-inf
832 baddNaN:+inf:NaN
833 baddNaN:+inf:NaN
834 +inf:baddNaN:NaN
835 -inf:baddNaN:NaN
836 +0:+0:+0
837 +1:+0:+1
838 +0:+1:+1
839 +1:+1:+2
840 -1:+0:-1
841 +0:-1:-1
842 -1:-1:-2
843 -1:+1:+0
844 +1:-1:+0
845 +9:+1:+10
846 +99:+1:+100
847 +999:+1:+1000
848 +9999:+1:+10000
849 +99999:+1:+100000
850 +999999:+1:+1000000
851 +9999999:+1:+10000000
852 +99999999:+1:+100000000
853 +999999999:+1:+1000000000
854 +9999999999:+1:+10000000000
855 +99999999999:+1:+100000000000
856 +10:-1:+9
857 +100:-1:+99
858 +1000:-1:+999
859 +10000:-1:+9999
860 +100000:-1:+99999
861 +1000000:-1:+999999
862 +10000000:-1:+9999999
863 +100000000:-1:+99999999
864 +1000000000:-1:+999999999
865 +10000000000:-1:+9999999999
866 +123456789:+987654321:+1111111110
867 -123456789:+987654321:+864197532
868 -123456789:-987654321:-1111111110
869 +123456789:-987654321:-864197532
870 &bsub
871 abc:abc:NaN
872 abc:+0:NaN
873 +0:abc:NaN
874 +inf:-inf:inf
875 -inf:+inf:-inf
876 +inf:+inf:0
877 -inf:-inf:0
878 +0:+0:+0
879 +1:+0:+1
880 +0:+1:-1
881 +1:+1:+0
882 -1:+0:-1
883 +0:-1:+1
884 -1:-1:+0
885 -1:+1:-2
886 +1:-1:+2
887 +9:+1:+8
888 +99:+1:+98
889 +999:+1:+998
890 +9999:+1:+9998
891 +99999:+1:+99998
892 +999999:+1:+999998
893 +9999999:+1:+9999998
894 +99999999:+1:+99999998
895 +999999999:+1:+999999998
896 +9999999999:+1:+9999999998
897 +99999999999:+1:+99999999998
898 +10:-1:+11
899 +100:-1:+101
900 +1000:-1:+1001
901 +10000:-1:+10001
902 +100000:-1:+100001
903 +1000000:-1:+1000001
904 +10000000:-1:+10000001
905 +100000000:-1:+100000001
906 +1000000000:-1:+1000000001
907 +10000000000:-1:+10000000001
908 +123456789:+987654321:-864197532
909 -123456789:+987654321:-1111111110
910 -123456789:-987654321:+864197532
911 +123456789:-987654321:+1111111110
912 &bmul
913 abc:abc:NaN
914 abc:+0:NaN
915 +0:abc:NaN
916 NaNmul:+inf:NaN
917 NaNmul:-inf:NaN
918 -inf:NaNmul:NaN
919 +inf:NaNmul:NaN
920 +inf:+inf:inf
921 +inf:-inf:-inf
922 -inf:+inf:-inf
923 -inf:-inf:inf
924 +0:+0:+0
925 +0:+1:+0
926 +1:+0:+0
927 +0:-1:+0
928 -1:+0:+0
929 +123456789123456789:+0:+0
930 +0:+123456789123456789:+0
931 -1:-1:+1
932 -1:+1:-1
933 +1:-1:-1
934 +1:+1:+1
935 +2:+3:+6
936 -2:+3:-6
937 +2:-3:-6
938 -2:-3:+6
939 +111:+111:+12321
940 +10101:+10101:+102030201
941 +1001001:+1001001:+1002003002001
942 +100010001:+100010001:+10002000300020001
943 +10000100001:+10000100001:+100002000030000200001
944 +11111111111:+9:+99999999999
945 +22222222222:+9:+199999999998
946 +33333333333:+9:+299999999997
947 +44444444444:+9:+399999999996
948 +55555555555:+9:+499999999995
949 +66666666666:+9:+599999999994
950 +77777777777:+9:+699999999993
951 +88888888888:+9:+799999999992
952 +99999999999:+9:+899999999991
953 +25:+25:+625
954 +12345:+12345:+152399025
955 +99999:+11111:+1111088889
956 9999:10000:99990000
957 99999:100000:9999900000
958 999999:1000000:999999000000
959 9999999:10000000:99999990000000
960 99999999:100000000:9999999900000000
961 999999999:1000000000:999999999000000000
962 9999999999:10000000000:99999999990000000000
963 99999999999:100000000000:9999999999900000000000
964 999999999999:1000000000000:999999999999000000000000
965 9999999999999:10000000000000:99999999999990000000000000
966 99999999999999:100000000000000:9999999999999900000000000000
967 999999999999999:1000000000000000:999999999999999000000000000000
968 9999999999999999:10000000000000000:99999999999999990000000000000000
969 99999999999999999:100000000000000000:9999999999999999900000000000000000
970 999999999999999999:1000000000000000000:999999999999999999000000000000000000
971 9999999999999999999:10000000000000000000:99999999999999999990000000000000000000
972 &bdiv-list
973 100:20:5,0
974 4095:4095:1,0
975 -4095:-4095:1,0
976 4095:-4095:-1,0
977 -4095:4095:-1,0
978 123:2:61,1
979 # inf handling and general remainder
980 5:8:0,5
981 0:8:0,0
982 11:2:5,1
983 11:-2:-5,-1
984 -11:2:-5,1
985 # see table in documentation in MBI
986 0:inf:0,0
987 0:-inf:0,0
988 5:inf:0,5
989 5:-inf:0,5
990 -5:inf:0,-5
991 -5:-inf:0,-5
992 inf:5:inf,0
993 -inf:5:-inf,0
994 inf:-5:-inf,0
995 -inf:-5:inf,0
996 5:5:1,0
997 -5:-5:1,0
998 inf:inf:1,0
999 -inf:-inf:1,0
1000 -inf:inf:-1,0
1001 inf:-inf:-1,0
1002 8:0:inf,8
1003 inf:0:inf,inf
1004 # exceptions to reminder rule
1005 -8:0:-inf,-8
1006 -inf:0:-inf,-inf
1007 0:0:NaN,NaN
1008 &bdiv
1009 abc:abc:NaN
1010 abc:+1:NaN
1011 +1:abc:NaN
1012 +0:+0:NaN
1013 # inf handling (see table in doc)
1014 0:inf:0
1015 0:-inf:0
1016 5:inf:0
1017 5:-inf:0
1018 -5:inf:0
1019 -5:-inf:0
1020 inf:5:inf
1021 -inf:5:-inf
1022 inf:-5:-inf
1023 -inf:-5:inf
1024 5:5:1
1025 -5:-5:1
1026 inf:inf:1
1027 -inf:-inf:1
1028 -inf:inf:-1
1029 inf:-inf:-1
1030 8:0:inf
1031 inf:0:inf
1032 -8:0:-inf
1033 -inf:0:-inf
1034 0:0:NaN
1035 11:2:5
1036 -11:-2:5
1037 -11:2:-5
1038 11:-2:-5
1039 +0:+1:+0
1040 +0:-1:+0
1041 +1:+1:+1
1042 -1:-1:+1
1043 +1:-1:-1
1044 -1:+1:-1
1045 +1:+2:+0
1046 +2:+1:+2
1047 +1:+26:+0
1048 +1000000000:+9:+111111111
1049 +2000000000:+9:+222222222
1050 +3000000000:+9:+333333333
1051 +4000000000:+9:+444444444
1052 +5000000000:+9:+555555555
1053 +6000000000:+9:+666666666
1054 +7000000000:+9:+777777777
1055 +8000000000:+9:+888888888
1056 +9000000000:+9:+1000000000
1057 +35500000:+113:+314159
1058 +71000000:+226:+314159
1059 +106500000:+339:+314159
1060 +1000000000:+3:+333333333
1061 +10:+5:+2
1062 +100:+4:+25
1063 +1000:+8:+125
1064 +10000:+16:+625
1065 +999999999999:+9:+111111111111
1066 +999999999999:+99:+10101010101
1067 +999999999999:+999:+1001001001
1068 +999999999999:+9999:+100010001
1069 +999999999999999:+99999:+10000100001
1070 +1111088889:+99999:+11111
1071 -5:-3:1
1072 -5:3:-1
1073 4:3:1
1074 4:-3:-1
1075 1:3:0
1076 1:-3:0
1077 -2:-3:0
1078 -2:3:0
1079 8:3:2
1080 -8:3:-2
1081 14:-3:-4
1082 -14:3:-4
1083 -14:-3:4
1084 14:3:4
1085 # bug in Calc with '99999' vs $BASE-1
1086 10000000000000000000000000000000000000000000000000000000000000000000000000000000000:10000000375084540248994272022843165711074:999999962491547381984643365663244474111576
1087 &bmod
1088 # inf handling, see table in doc
1089 0:inf:0
1090 0:-inf:0
1091 5:inf:5
1092 5:-inf:5
1093 -5:inf:-5
1094 -5:-inf:-5
1095 inf:5:0
1096 -inf:5:0
1097 inf:-5:0
1098 -inf:-5:0
1099 5:5:0
1100 -5:-5:0
1101 inf:inf:0
1102 -inf:-inf:0
1103 -inf:inf:0
1104 inf:-inf:0
1105 8:0:8
1106 inf:0:inf
1107 # exceptions to reminder rule
1108 -inf:0:-inf
1109 -8:0:-8
1110 0:0:NaN
1111 abc:abc:NaN
1112 abc:+1:abc:NaN
1113 +1:abc:NaN
1114 +0:+0:NaN
1115 +0:+1:+0
1116 +1:+0:+1
1117 +0:-1:+0
1118 -1:+0:-1
1119 +1:+1:+0
1120 -1:-1:+0
1121 +1:-1:+0
1122 -1:+1:+0
1123 +1:+2:+1
1124 +2:+1:+0
1125 +1000000000:+9:+1
1126 +2000000000:+9:+2
1127 +3000000000:+9:+3
1128 +4000000000:+9:+4
1129 +5000000000:+9:+5
1130 +6000000000:+9:+6
1131 +7000000000:+9:+7
1132 +8000000000:+9:+8
1133 +9000000000:+9:+0
1134 +35500000:+113:+33
1135 +71000000:+226:+66
1136 +106500000:+339:+99
1137 +1000000000:+3:+1
1138 +10:+5:+0
1139 +100:+4:+0
1140 +1000:+8:+0
1141 +10000:+16:+0
1142 +999999999999:+9:+0
1143 +999999999999:+99:+0
1144 +999999999999:+999:+0
1145 +999999999999:+9999:+0
1146 +999999999999999:+99999:+0
1147 -9:+5:+1
1148 +9:-5:-1
1149 -9:-5:-4
1150 -5:3:1
1151 -2:3:1
1152 4:3:1
1153 1:3:1
1154 -5:-3:-2
1155 -2:-3:-2
1156 4:-3:-2
1157 1:-3:-2
1158 4095:4095:0
1159 &bgcd
1160 abc:abc:NaN
1161 abc:+0:NaN
1162 +0:abc:NaN
1163 +0:+0:+0
1164 +0:+1:+1
1165 +1:+0:+1
1166 +1:+1:+1
1167 +2:+3:+1
1168 +3:+2:+1
1169 -3:+2:+1
1170 +100:+625:+25
1171 +4096:+81:+1
1172 +1034:+804:+2
1173 +27:+90:+56:+1
1174 +27:+90:+54:+9
1175 &blcm
1176 abc:abc:NaN
1177 abc:+0:NaN
1178 +0:abc:NaN
1179 +0:+0:NaN
1180 +1:+0:+0
1181 +0:+1:+0
1182 +27:+90:+270
1183 +1034:+804:+415668
1184 &band
1185 abc:abc:NaN
1186 abc:0:NaN
1187 0:abc:NaN
1188 1:2:0
1189 3:2:2
1190 +8:+2:+0
1191 +281474976710656:+0:+0
1192 +281474976710656:+1:+0
1193 +281474976710656:+281474976710656:+281474976710656
1194 -2:-3:-4
1195 -1:-1:-1
1196 -6:-6:-6
1197 -7:-4:-8
1198 -7:4:0
1199 -4:7:4
1200 &bior
1201 abc:abc:NaN
1202 abc:0:NaN
1203 0:abc:NaN
1204 1:2:3
1205 +8:+2:+10
1206 +281474976710656:+0:+281474976710656
1207 +281474976710656:+1:+281474976710657
1208 +281474976710656:+281474976710656:+281474976710656
1209 -2:-3:-1
1210 -1:-1:-1
1211 -6:-6:-6
1212 -7:4:-3
1213 -4:7:-1
1214 &bxor
1215 abc:abc:NaN
1216 abc:0:NaN
1217 0:abc:NaN
1218 1:2:3
1219 +8:+2:+10
1220 +281474976710656:+0:+281474976710656
1221 +281474976710656:+1:+281474976710657
1222 +281474976710656:+281474976710656:+0
1223 -2:-3:3
1224 -1:-1:0
1225 -6:-6:0
1226 -7:4:-3
1227 -4:7:-5
1228 4:-7:-3
1229 -4:-7:5
1230 &bnot
1231 abc:NaN
1232 +0:-1
1233 +8:-9
1234 +281474976710656:-281474976710657
1235 -1:0
1236 -2:1
1237 -12:11
1238 &digit
1239 0:0:0
1240 12:0:2
1241 12:1:1
1242 123:0:3
1243 123:1:2
1244 123:2:1
1245 123:-1:1
1246 123:-2:2
1247 123:-3:3
1248 123456:0:6
1249 123456:1:5
1250 123456:2:4
1251 123456:3:3
1252 123456:4:2
1253 123456:5:1
1254 123456:-1:1
1255 123456:-2:2
1256 123456:-3:3
1257 100000:-3:0
1258 100000:0:0
1259 100000:1:0
1260 &mantissa
1261 abc:NaN
1262 1e4:1
1263 2e0:2
1264 123:123
1265 -1:-1
1266 -2:-2
1267 +inf:inf
1268 -inf:-inf
1269 &exponent
1270 abc:NaN
1271 1e4:4
1272 2e0:0
1273 123:0
1274 -1:0
1275 -2:0
1276 0:1
1277 +inf:inf
1278 -inf:inf
1279 &parts
1280 abc:NaN,NaN
1281 1e4:1,4
1282 2e0:2,0
1283 123:123,0
1284 -1:-1,0
1285 -2:-2,0
1286 0:0,1
1287 +inf:inf,inf
1288 -inf:-inf,inf
1289 &bpow
1290 abc:12:NaN
1291 12:abc:NaN
1292 0:0:1
1293 0:1:0
1294 0:2:0
1295 0:-1:NaN
1296 0:-2:NaN
1297 1:0:1
1298 1:1:1
1299 1:2:1
1300 1:3:1
1301 1:-1:1
1302 1:-2:1
1303 1:-3:1
1304 2:0:1
1305 2:1:2
1306 2:2:4
1307 2:3:8
1308 3:3:27
1309 2:-1:NaN
1310 -2:-1:NaN
1311 2:-2:NaN
1312 -2:-2:NaN
1313 +inf:1234500012:inf
1314 -inf:1234500012:-inf
1315 +inf:-12345000123:inf
1316 -inf:-12345000123:-inf
1317 # 1 ** -x => 1 / (1 ** x)
1318 -1:0:1
1319 -2:0:1
1320 -1:1:-1
1321 -1:2:1
1322 -1:3:-1
1323 -1:4:1
1324 -1:5:-1
1325 -1:-1:-1
1326 -1:-2:1
1327 -1:-3:-1
1328 -1:-4:1
1329 10:2:100
1330 10:3:1000
1331 10:4:10000
1332 10:5:100000
1333 10:6:1000000
1334 10:7:10000000
1335 10:8:100000000
1336 10:9:1000000000
1337 10:20:100000000000000000000
1338 123456:2:15241383936
1339 &length
1340 100:3
1341 10:2
1342 1:1
1343 0:1
1344 12345:5
1345 10000000000000000:17
1346 -123:3
1347 215960156869840440586892398248:30
1348 &bsqrt
1349 144:12
1350 16:4
1351 4:2
1352 2:1
1353 12:3
1354 256:16
1355 100000000:10000
1356 4000000000000:2000000
1357 1:1
1358 0:0
1359 -2:NaN
1360 Nan:NaN
1361 &bround
1362 $round_mode('trunc')
1363 0:12:0
1364 NaNbround:12:NaN
1365 +inf:12:inf
1366 -inf:12:-inf
1367 1234:0:1234
1368 1234:2:1200
1369 123456:4:123400
1370 123456:5:123450
1371 123456:6:123456
1372 +10123456789:5:+10123000000
1373 -10123456789:5:-10123000000
1374 +10123456789:9:+10123456700
1375 -10123456789:9:-10123456700
1376 +101234500:6:+101234000
1377 -101234500:6:-101234000
1378 #+101234500:-4:+101234000
1379 #-101234500:-4:-101234000
1380 $round_mode('zero')
1381 +20123456789:5:+20123000000
1382 -20123456789:5:-20123000000
1383 +20123456789:9:+20123456800
1384 -20123456789:9:-20123456800
1385 +201234500:6:+201234000
1386 -201234500:6:-201234000
1387 #+201234500:-4:+201234000
1388 #-201234500:-4:-201234000
1389 +12345000:4:12340000
1390 -12345000:4:-12340000
1391 $round_mode('+inf')
1392 +30123456789:5:+30123000000
1393 -30123456789:5:-30123000000
1394 +30123456789:9:+30123456800
1395 -30123456789:9:-30123456800
1396 +301234500:6:+301235000
1397 -301234500:6:-301234000
1398 #+301234500:-4:+301235000
1399 #-301234500:-4:-301234000
1400 +12345000:4:12350000
1401 -12345000:4:-12340000
1402 $round_mode('-inf')
1403 +40123456789:5:+40123000000
1404 -40123456789:5:-40123000000
1405 +40123456789:9:+40123456800
1406 -40123456789:9:-40123456800
1407 +401234500:6:+401234000
1408 +401234500:6:+401234000
1409 #-401234500:-4:-401235000
1410 #-401234500:-4:-401235000
1411 +12345000:4:12340000
1412 -12345000:4:-12350000
1413 $round_mode('odd')
1414 +50123456789:5:+50123000000
1415 -50123456789:5:-50123000000
1416 +50123456789:9:+50123456800
1417 -50123456789:9:-50123456800
1418 +501234500:6:+501235000
1419 -501234500:6:-501235000
1420 #+501234500:-4:+501235000
1421 #-501234500:-4:-501235000
1422 +12345000:4:12350000
1423 -12345000:4:-12350000
1424 $round_mode('even')
1425 +60123456789:5:+60123000000
1426 -60123456789:5:-60123000000
1427 +60123456789:9:+60123456800
1428 -60123456789:9:-60123456800
1429 +601234500:6:+601234000
1430 -601234500:6:-601234000
1431 #+601234500:-4:+601234000
1432 #-601234500:-4:-601234000
1433 #-601234500:-9:0
1434 #-501234500:-9:0
1435 #-601234500:-8:0
1436 #-501234500:-8:0
1437 +1234567:7:1234567
1438 +1234567:6:1234570
1439 +12345000:4:12340000
1440 -12345000:4:-12340000
1441 &is_zero
1442 0:1
1443 NaNzero:0
1444 +inf:0
1445 -inf:0
1446 123:0
1447 -1:0
1448 1:0
1449 &is_one
1450 0:0
1451 NaNone:0
1452 +inf:0
1453 -inf:0
1454 1:1
1455 2:0
1456 -1:0
1457 -2:0
1458 # floor and ceil tests are pretty pointless in integer space...but play safe
1459 &bfloor
1460 0:0
1461 NaNfloor:NaN
1462 +inf:inf
1463 -inf:-inf
1464 -1:-1
1465 -2:-2
1466 2:2
1467 3:3
1468 abc:NaN
1469 &bceil
1470 NaNceil:NaN
1471 +inf:inf
1472 -inf:-inf
1473 0:0
1474 -1:-1
1475 -2:-2
1476 2:2
1477 3:3
1478 abc:NaN
1479 &as_hex
1480 128:0x80
1481 -128:-0x80
1482 0:0x0
1483 -0:0x0
1484 1:0x1
1485 0x123456789123456789:0x123456789123456789
1486 +inf:inf
1487 -inf:-inf
1488 NaNas_hex:NaN
1489 &as_bin
1490 128:0b10000000
1491 -128:-0b10000000
1492 0:0b0
1493 -0:0b0
1494 1:0b1
1495 0b1010111101010101010110110110110110101:0b1010111101010101010110110110110110101
1496 +inf:inf
1497 -inf:-inf
1498 NaNas_bin:NaN