#include this file into another test for subclass testing... ok ($class->config()->{lib},$CL); $setup = ''; while () { chomp; $_ =~ s/#.*$//; # remove comments $_ =~ s/\s+$//; # trailing spaces next if /^$/; # skip empty lines & comments if (s/^&//) { $f = $_; } elsif (/^\$/) { $setup = $_; $setup =~ s/\$/\$${class}::/g; # round_mode, div_scale #print "\$setup== $setup\n"; } else { if (m|^(.*?):(/.+)$|) { $ans = $2; @args = split(/:/,$1,99); } else { @args = split(/:/,$_,99); $ans = pop(@args); } $try = "\$x = new $class \"$args[0]\";"; if ($f eq "bnorm") { $try .= "\$x;"; } elsif ($f eq "finf") { my $a = $args[1] || ''; $try .= "\$x->binf('$a');"; } elsif ($f eq "is_inf") { $try .= "\$x->is_inf('$args[1]');"; } elsif ($f eq "fone") { $try .= "\$x->bone('$args[1]');"; } elsif ($f eq "fstr") { $try .= "\$x->accuracy($args[1]); \$x->precision($args[2]);"; $try .= '$x->bstr();'; } elsif ($f eq "parts") { # ->bstr() to see if an object is returned $try .= '($a,$b) = $x->parts(); $a = $a->bstr(); $b = $b->bstr();'; $try .= '"$a $b";'; } elsif ($f eq "numerator") { # ->bstr() to see if an object is returned $try .= '$x->numerator()->bstr();'; } elsif ($f eq "denominator") { # ->bstr() to see if an object is returned $try .= '$x->denominator()->bstr();'; } elsif ($f =~ /^(length|numify)$/) { $try .= "\$x->$f();"; # some unary ops (can't test the fxxx form, since no AUTOLOAD in BigRat) } elsif ($f =~ /^f(nan|sstr|neg|floor|ceil|abs)$/) { $try .= "\$x->b$1();"; # some is_xxx test function } elsif ($f =~ /^is_(zero|one|negative|positive|odd|even|nan|int)$/) { $try .= "\$x->$f();"; } elsif ($f eq "as_number") { $try .= '$x->as_number();'; } elsif ($f eq "finc") { $try .= '++$x;'; } elsif ($f eq "fdec") { $try .= '--$x;'; } elsif ($f eq "digit") { $try .= "\$x->digit($args[1]);"; } elsif ($f eq "fround") { $try .= "$setup; \$x->bround($args[1]);"; } elsif ($f eq "ffround") { $try .= "$setup; \$x->bfround($args[1]);"; } elsif ($f eq "fsqrt") { $try .= "$setup; \$x->bsqrt();"; } elsif ($f eq "flog") { $try .= "$setup; \$x->blog();"; } elsif ($f eq "ffac") { $try .= "$setup; \$x->bfac();"; } else { $try .= "\$y = new $class \"$args[1]\";"; if ($f eq "bcmp") { $try .= '$x <=> $y;'; } elsif ($f eq "bacmp") { $try .= '$x->bacmp($y);'; } elsif ($f eq "bpow") { $try .= '$x ** $y;'; } elsif ($f eq "fpow") { $try .= '$x->bpow($y);'; } elsif ($f eq "badd") { $try .= '$x + $y;'; } elsif ($f eq "bsub") { $try .= '$x - $y;'; } elsif ($f eq "bmul") { $try .= '$x * $y;'; } elsif ($f eq "bdiv") { $try .= "$setup; \$x / \$y;"; } elsif ($f eq "fdiv-list") { $try .= "$setup; join(',',\$x->bdiv(\$y));"; } elsif ($f eq "brsft") { $try .= '$x >> $y;'; } elsif ($f eq "blsft") { $try .= '$x << $y;'; } elsif ($f eq "bmod") { $try .= '$x % $y;'; } elsif( $f eq "bmodinv") { $try .= "\$x->bmodinv(\$y);"; } elsif( $f eq "blog") { $try .= "\$x->blog(\$y);"; } else { $try .= "\$z = $class->new(\"$args[2]\");"; # Functions with three arguments if( $f eq "bmodpow") { $try .= "\$x->bmodpow(\$y,\$z);"; } else { warn "Unknown op '$f'"; } } } # print "# Trying: '$try'\n"; $ans1 = eval $try; if ($ans =~ m|^/(.*)$|) { my $pat = $1; if ($ans1 =~ /$pat/) { ok (1,1); } else { print "# '$try' expected: /$pat/ got: '$ans1'\n" if !ok(1,0); } } else { if ($ans eq "") { ok_undef ($ans1); } else { print "# Tried: '$try'\n" if !ok ($ans1, $ans); # if (ref($ans1) eq "$class") # { # # float numbers are normalized (for now), so mantissa shouldn't have # # trailing zeros # #print $ans1->_trailing_zeros(),"\n"; # print "# Has trailing zeros after '$try'\n" # if !ok ($ans1->{_m}->_trailing_zeros(), 0); # } } } # end pattern or string } } # end while # check whether $class->new( Math::BigInt->new()) destroys it # ($y == 12 in this case) $x = Math::BigInt->new(1200); $y = $class->new($x); ok ($y,1200); ok ($x,1200); ############################################################################### # zero,inf,one,nan $x = $class->new(2); $x->bzero(); ok_undef ($x->{_a}); ok_undef ($x->{_p}); $x = $class->new(2); $x->binf(); ok_undef ($x->{_a}); ok_undef ($x->{_p}); $x = $class->new(2); $x->bone(); ok_undef ($x->{_a}); ok_undef ($x->{_p}); $x = $class->new(2); $x->bnan(); ok_undef ($x->{_a}); ok_undef ($x->{_p}); 1; # all done ############################################################################### # Perl 5.005 does not like ok ($x,undef) sub ok_undef { my $x = shift; ok (1,1) and return if !defined $x; ok ($x,'undef'); } __DATA__ &digit 123:2:1 1234:0:4 1234:1:3 1234:2:2 1234:3:1 1234:-1:1 1234:-2:2 1234:-3:3 1234:-4:4 0:0:0 0:1:0 &bmodinv # format: number:modulus:result # bmodinv Data errors abc:abc:NaN abc:5:NaN 5:abc:NaN # bmodinv Expected Results from normal use 1:5:1 3:5:2 -2:5:2 8:5033:4404 1234567891:13:6 -1234567891:13:7 324958749843759385732954874325984357439658735983745:2348249874968739:1741662881064902 ## bmodinv Error cases / useless use of function 3:-5:NaN inf:5:NaN 5:inf:NaN -inf:5:NaN 5:-inf:NaN &as_number 144/7:20 NaN:NaN +inf:inf -inf:-inf &bmodpow # format: number:exponent:modulus:result # bmodpow Data errors abc:abc:abc:NaN 5:abc:abc:NaN abc:5:abc:NaN abc:abc:5:NaN 5:5:abc:NaN 5:abc:5:NaN abc:5:5:NaN # bmodpow Expected results 0:0:2:1 1:0:2:1 0:0:1:0 8:7:5032:3840 8:-1:5033:4404 98436739867439843769485798542749827593285729587325:43698764986460981048259837659386739857456983759328457:6943857329857295827698367:3104744730915914415259518 # bmodpow Error cases 8:8:-5:NaN 8:-1:16:NaN inf:5:13:NaN 5:inf:13:NaN &bmod NaN:1:NaN 1:NaN:NaN 1:1:0 2:2:0 12:6:0 7/4:4/14:1/28 7/4:4/16:0 -7/4:4/16:0 -7/4:-4/16:0 7/4:-4/16:0 7/4:4/32:0 -7/4:4/32:0 -7/4:-4/32:0 7/4:-4/32:0 7/4:4/28:1/28 -7/4:4/28:-1/28 7/4:-4/28:1/28 -7/4:-4/28:-1/28 &fsqrt 1:1 0:0 NaN:NaN +inf:inf -inf:NaN 144:12 # sqrt(144) / sqrt(4) = 12/2 = 6/1 144/4:6 25/16:5/4 -3:NaN &flog NaN:NaN 0:NaN -2:NaN &blog NaN:NaN:NaN 0:NaN:NaN NaN:0:NaN NaN:1:NaN 1:NaN:NaN 0:2:NaN 0:-2:NaN 3:-2:NaN &finf 1:+:inf 2:-:-inf 3:abc:inf &numify 0:0 +1:1 1234:1234 3/4:0.75 5/2:2.5 3/2:1.5 5/4:1.25 NaN:NaN +inf:inf -inf:-inf &fnan abc:NaN 2:NaN -2:NaN 0:NaN &fone 2:+:1 -2:-:-1 -2:+:1 2:-:-1 0::1 -2::1 abc::1 2:abc:1 &fsstr +inf:inf -inf:-inf abcfsstr:NaN 1:1/1 3/1:3/1 0.1:1/10 &bnorm 1:1 -0:0 bnormNaN:NaN +inf:inf -inf:-inf inf/inf:NaN 5/inf:0 5/-inf:0 inf/5:inf -inf/5:-inf inf/-5:-inf -inf/-5:inf 123:123 -123.4567:-1234567/10000 # invalid inputs 1__2:NaN 1E1__2:NaN 11__2E2:NaN #1.E3:NaN .2E-3.:NaN #1e3e4:NaN .2E2:20 inf:inf +inf:inf -inf:-inf +infinity:NaN +-inf:NaN abc:NaN 1 a:NaN 1bcd2:NaN 11111b:NaN +1z:NaN -1z:NaN 0:0 +0:0 +00:0 +0_0_0:0 000000_0000000_00000:0 -0:0 -0000:0 +1:1 +01:1 +001:1 +00000100000:100000 +00000800/00000010:80 -00000800/00000010:-80 +00000800/-00000010:-80 -00000800/-00000010:80 123456789:123456789 -1:-1 -01:-1 -001:-1 -123456789:-123456789 -00000100000:-100000 123.456a:NaN 123.456:15432/125 0.01:1/100 .002:1/500 +.2:1/5 -0.0003:-3/10000 -.0000000004:-1/2500000000 123456E2:12345600 123456E-2:30864/25 -123456E2:-12345600 -123456E-2:-30864/25 1e1:10 2e-11:1/50000000000 12/10:6/5 0.1/0.1:1 100/0.1:1000 0.1/10:1/100 1 / 3:1/3 1/ 3:1/3 1 /3:1/3 &fneg fnegNaN:NaN +inf:-inf -inf:inf +0:0 +1:-1 -1:1 +123456789:-123456789 -123456789:123456789 +123.456789:-123456789/1000000 -123456.789:123456789/1000 &fabs fabsNaN:NaN +inf:inf -inf:inf +0:0 +1:1 -1:1 +123456789:123456789 -123456789:123456789 +123.456789:123456789/1000000 -123456.789:123456789/1000 &badd abc:abc:NaN abc:+0:NaN +0:abc:NaN +inf:-inf:NaN -inf:+inf:NaN +inf:+inf:inf -inf:-inf:-inf baddNaN:+inf:NaN baddNaN:+inf:NaN +inf:baddNaN:NaN -inf:baddNaN:NaN +0:+0:0 +1:+0:1 +0:+1:1 +1:+1:2 -1:+0:-1 +0:-1:-1 -1:-1:-2 -1:+1:0 +1:-1:0 +9:+1:10 +99:+1:100 +999:+1:1000 +9999:+1:10000 +99999:+1:100000 +999999:+1:1000000 +9999999:+1:10000000 +99999999:+1:100000000 +999999999:+1:1000000000 +9999999999:+1:10000000000 +99999999999:+1:100000000000 +10:-1:9 +100:-1:99 +1000:-1:999 +10000:-1:9999 +100000:-1:99999 +1000000:-1:999999 +10000000:-1:9999999 +100000000:-1:99999999 +1000000000:-1:999999999 +10000000000:-1:9999999999 +123456789:+987654321:1111111110 -123456789:+987654321:864197532 -123456789:-987654321:-1111111110 +123456789:-987654321:-864197532 1/3:1/3:2/3 2/3:-1/3:1/3 &bsub abc:abc:NaN abc:+0:NaN +0:abc:NaN +inf:-inf:inf -inf:+inf:-inf +inf:+inf:NaN -inf:-inf:NaN baddNaN:+inf:NaN baddNaN:+inf:NaN +inf:baddNaN:NaN -inf:baddNaN:NaN +0:+0:0 +1:+0:1 +0:+1:-1 +1:+1:0 -1:+0:-1 +0:-1:1 -1:-1:0 -1:+1:-2 +1:-1:2 +9:+1:8 +99:+1:98 +999:+1:998 +9999:+1:9998 +99999:+1:99998 +999999:+1:999998 +9999999:+1:9999998 +99999999:+1:99999998 +999999999:+1:999999998 +9999999999:+1:9999999998 +99999999999:+1:99999999998 +10:-1:11 +100:-1:101 +1000:-1:1001 +10000:-1:10001 +100000:-1:100001 +1000000:-1:1000001 +10000000:-1:10000001 +100000000:-1:100000001 +1000000000:-1:1000000001 +10000000000:-1:10000000001 +123456789:+987654321:-864197532 -123456789:+987654321:-1111111110 -123456789:-987654321:864197532 +123456789:-987654321:1111111110 2/3:1/3:1/3 7/27:3/54:11/54 -2/3:+2/3:-4/3 -2/3:-2/3:0 0:-123:123 0:123:-123 &bmul abc:abc:NaN abc:+0:NaN +0:abc:NaN +inf:NaNmul:NaN +inf:NaNmul:NaN NaNmul:+inf:NaN NaNmul:-inf:NaN +inf:+inf:inf +inf:-inf:-inf +inf:-inf:-inf +inf:+inf:inf +inf:123.34:inf +inf:-123.34:-inf -inf:123.34:-inf -inf:-123.34:inf 123.34:+inf:inf -123.34:+inf:-inf 123.34:-inf:-inf -123.34:-inf:inf +0:+0:0 +0:+1:0 +1:+0:0 +0:-1:0 -1:+0:0 +123456789123456789:+0:0 +0:+123456789123456789:0 -1:-1:1 -1:+1:-1 +1:-1:-1 +1:+1:1 +2:+3:6 -2:+3:-6 +2:-3:-6 -2:-3:6 +111:+111:12321 +10101:+10101:102030201 +1001001:+1001001:1002003002001 +100010001:+100010001:10002000300020001 +10000100001:+10000100001:100002000030000200001 +11111111111:+9:99999999999 +22222222222:+9:199999999998 +33333333333:+9:299999999997 +44444444444:+9:399999999996 +55555555555:+9:499999999995 +66666666666:+9:599999999994 +77777777777:+9:699999999993 +88888888888:+9:799999999992 +99999999999:+9:899999999991 6:120:720 10:10000:100000 1/4:1/3:1/12 &bdiv $div_scale = 40; $round_mode = 'even' abc:abc:NaN abc:+1:abc:NaN +1:abc:NaN -1:abc:NaN 0:abc:NaN +0:+0:NaN +0:+1:0 +1:+0:inf +3214:+0:inf +0:-1:0 -1:+0:-inf -3214:+0:-inf +1:+1:1 -1:-1:1 +1:-1:-1 -1:+1:-1 +1:+2:1/2 +2:+1:2 123:+inf:0 123:-inf:0 +10:+5:2 +100:+4:25 +1000:+8:125 +10000:+16:625 +10000:-16:-625 +999999999999:+9:111111111111 +999999999999:+99:10101010101 +999999999999:+999:1001001001 +999999999999:+9999:100010001 +999999999999999:+99999:10000100001 +1000000000:+9:1000000000/9 +2000000000:+9:2000000000/9 +3000000000:+9:1000000000/3 +4000000000:+9:4000000000/9 +5000000000:+9:5000000000/9 +6000000000:+9:2000000000/3 +7000000000:+9:7000000000/9 +8000000000:+9:8000000000/9 +9000000000:+9:1000000000 +35500000:+113:35500000/113 +71000000:+226:35500000/113 +106500000:+339:35500000/113 +1000000000:+3:1000000000/3 2:25.024996000799840031993601279744051189762:1000000000000000000000000000000000000000/12512498000399920015996800639872025594881 123456:1:123456 1/4:1/3:3/4 # reset scale for further tests $div_scale = 40 &is_nan 123:0 abc:1 NaN:1 -123:0 &is_inf +inf::1 -inf::1 abc::0 1::0 NaN::0 -1::0 +inf:-:0 +inf:+:1 -inf:-:1 -inf:+:0 # it must be exactly /^[+-]inf$/ +infinity::0 -infinity::0 &is_odd abc:0 0:0 -1:1 -3:1 1:1 3:1 1000001:1 1000002:0 +inf:0 -inf:0 123.45:0 -123.45:0 2:0 &is_int NaNis_int:0 0:1 1:1 2:1 -2:1 -1:1 -inf:0 +inf:0 123.4567:0 -0.1:0 -0.002:0 1/3:0 3/1:1 &is_even abc:0 0:1 -1:0 -3:0 1:0 3:0 1000001:0 1000002:1 2:1 +inf:0 -inf:0 123.456:0 -123.456:0 0.01:0 -0.01:0 120:1 1200:1 -1200:1 &is_positive 0:1 1:1 -1:0 -123:0 NaN:0 -inf:0 +inf:1 &is_negative 0:0 1:0 -1:1 -123:1 NaN:0 -inf:1 +inf:0 &parts 0:0 1 1:1 1 123:123 1 -123:-123 1 -1200:-1200 1 5/7:5 7 -5/7:-5 7 NaNparts:NaN NaN +inf:inf inf -inf:-inf inf &length 123:3 -123:3 0:1 1:1 12345678901234567890:20 &is_zero NaNzero:0 +inf:0 -inf:0 0:1 -1:0 1:0 0/3:1 1/3:0 -0/3:1 5/inf:1 &is_one NaNone:0 +inf:0 -inf:0 0:0 2:0 1:1 -1:0 -2:0 1/3:0 100/100:1 0.1/0.1:1 5/inf:0 &ffloor 0:0 abc:NaN +inf:inf -inf:-inf 1:1 -51:-51 -51.2:-52 12.2:12 3/7:0 6/7:0 7/7:1 8/7:1 13/7:1 14/7:2 15/7:2 -3/7:-1 -6/7:-1 -7/1:-7 -8/7:-2 -13/7:-2 -14/7:-2 -15/7:-3 &fceil 0:0 abc:NaN +inf:inf -inf:-inf 1:1 -51:-51 -51.2:-51 12.2:13 3/7:1 6/7:1 8/7:2 13/7:2 14/7:2 15/7:3 -3/7:0 -6/7:0 -8/7:-1 -13/7:-1 -14/7:-2 -15/7:-2 &ffac NaN:NaN 1:1 -1:NaN &bpow # bpow test for overload of ** 2:2:4 3:3:27 &bacmp +0:-0:0 +0:+1:-1 -1:+1:0 +1:-1:0 -1:+2:-1 +2:-1:1 -123456789:+987654321:-1 +123456789:-987654321:-1 +987654321:+123456789:1 -987654321:+123456789:1 -123:+4567889:-1 # NaNs acmpNaN:123: 123:acmpNaN: acmpNaN:acmpNaN: # infinity +inf:+inf:0 -inf:-inf:0 +inf:-inf:0 -inf:+inf:0 +inf:123:1 -inf:123:1 +inf:-123:1 -inf:-123:1 +inf:1/23:1 -inf:1/23:1 +inf:-1/23:1 -inf:-1/23:1 +inf:12/3:1 -inf:12/3:1 +inf:-12/3:1 -inf:-12/3:1 123:inf:-1 -123:inf:-1 123:-inf:-1 -123:-inf:-1 1/23:inf:-1 -1/23:inf:-1 1/23:-inf:-1 -1/23:-inf:-1 12/3:inf:-1 -12/3:inf:-1 12/3:-inf:-1 -12/3:-inf:-1 # return undef +inf:NaN: NaN:inf: -inf:NaN: NaN:-inf: 1/3:2/3:-1 2/3:1/3:1 2/3:2/3:0 &fpow 2/1:3/1:8 3/1:3/1:27 5/2:3/1:125/8 -2/1:3/1:-8 -3/1:3/1:-27 -5/2:3/1:-125/8 -2/1:4/1:16 -3/1:4/1:81 -5/2:4/1:625/16 -5/2:-4/1:16/625 1/5:-3:125 -1/5:-3:-125 &numerator NaN:NaN inf:inf -inf:-inf 3/7:3 -3/7:-3 0:0 1:1 5/-3:-5 &denominator NaN:NaN inf:1 -inf:1 3/7:7 0:1 1/1:1 -1/1:1 -3/7:7 4/-5:5 &finc 3/2:5/2 -15/6:-3/2 NaN:NaN -1/3:2/3 -2/7:5/7 &fdec 15/6:3/2 -3/2:-5/2 1/3:-2/3 2/7:-5/7 NaN:NaN