This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade to Math::BigInt 1.59.
[perl5.git] / lib / Math / BigInt / t / bigintpm.inc
index 137ead4..01b77b8 100644 (file)
@@ -40,7 +40,7 @@ my ($f,$z,$a,$exp,@a,$m,$e,$round_mode,$expected_class);
 
 while (<DATA>) 
   {
-  chop;
+  chomp;
   next if /^#/;        # skip comments
   if (s/^&//) 
     {
@@ -163,9 +163,18 @@ while (<DATA>)
         $try .= "\$x ^ \$y;";
       }elsif ($f eq "bpow"){
         $try .= "\$x ** \$y;";
+      } elsif( $f eq "bmodinv") {
+       $try .= "\$x->bmodinv(\$y);";
       }elsif ($f eq "digit"){
-        $try = "\$x = $class->new('$args[0]'); \$x->digit($args[1]);";
-      } else { warn "Unknown op '$f'"; }
+        $try .= "\$x->digit(\$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'"; }
+      }
     } # end else all other ops
 
   $ans1 = eval $try;
@@ -208,6 +217,7 @@ $try .= '$a = $x->bpow($x);';
 $ans1 = eval $try;
 print "# Tried: '$try'\n" if !ok ($ans1, $class->new(10) ** 10);
 
+###############################################################################
 # test whether op destroys args or not (should better not)
 
 $x = $class->new(3);
@@ -240,6 +250,36 @@ ok ($x, -5);
 $x = $class->new(-5); $y = abs($x);
 ok ($x, -5);
 
+$x = $class->new(8);
+$y = $class->new(-1);
+$z = $class->new(5033);
+my $u = $x->copy()->bmodpow($y,$z);
+ok ($u,4404);
+ok ($y,-1);
+ok ($z,5033);
+
+$x = $class->new(-5); $y = -$x; ok ($x,-5); ok ($y,5);
+$x = $class->new(-5); $y = $x->copy()->bneg(); ok ($x,-5); ok ($y,5);
+
+$x = $class->new(-5); $y = $class->new(3); $x->bmul($y); ok ($x,-15); ok ($y,3);
+$x = $class->new(-5); $y = $class->new(3); $x->badd($y); ok ($x,-2); ok ($y,3);
+$x = $class->new(-5); $y = $class->new(3); $x->bsub($y); ok ($x,-8); ok ($y,3);
+$x = $class->new(-15); $y = $class->new(3); $x->bdiv($y); ok ($x,-5); ok ($y,3);
+$x = $class->new(-5); $y = $class->new(3); $x->bmod($y); ok ($x,1); ok ($y,3);
+
+$x = $class->new(5); $y = $class->new(3); $x->bmul($y); ok ($x,15); ok ($y,3);
+$x = $class->new(5); $y = $class->new(3); $x->badd($y); ok ($x,8); ok ($y,3);
+$x = $class->new(5); $y = $class->new(3); $x->bsub($y); ok ($x,2); ok ($y,3);
+$x = $class->new(15); $y = $class->new(3); $x->bdiv($y); ok ($x,5); ok ($y,3);
+$x = $class->new(5); $y = $class->new(3); $x->bmod($y); ok ($x,2); ok ($y,3);
+
+$x = $class->new(5); $y = $class->new(-3); $x->bmul($y); ok ($x,-15); ok($y,-3);
+$x = $class->new(5); $y = $class->new(-3); $x->badd($y); ok ($x,2); ok($y,-3);
+$x = $class->new(5); $y = $class->new(-3); $x->bsub($y); ok ($x,8); ok($y,-3);
+$x = $class->new(15); $y = $class->new(-3); $x->bdiv($y); ok ($x,-5); ok($y,-3);
+$x = $class->new(5); $y = $class->new(-3); $x->bmod($y); ok ($x,-1); ok($y,-3);
+
+###############################################################################
 # check whether overloading cmp works
 $try = "\$x = $class->new(0);";
 $try .= "\$y = 10;";
@@ -311,25 +351,25 @@ $x = Math::BigInt->new(0); if (!$x) { ok (1,1); } else { ok($x,'to be false') }
 
 @args = Math::BigInt::objectify(2,4,5);
 ok (scalar @args,3);           # $class, 4, 5
-ok ($args[0],$class);
+ok ($args[0] =~ /^Math::BigInt/);
 ok ($args[1],4);
 ok ($args[2],5);
 
 @args = Math::BigInt::objectify(0,4,5);
 ok (scalar @args,3);           # $class, 4, 5
-ok ($args[0],$class);
+ok ($args[0] =~ /^Math::BigInt/);
 ok ($args[1],4);
 ok ($args[2],5);
 
 @args = Math::BigInt::objectify(2,4,5);
 ok (scalar @args,3);           # $class, 4, 5
-ok ($args[0],$class);
+ok ($args[0] =~ /^Math::BigInt/);
 ok ($args[1],4);
 ok ($args[2],5);
 
 @args = Math::BigInt::objectify(2,4,5,6,7);
 ok (scalar @args,5);           # $class, 4, 5, 6, 7
-ok ($args[0],$class);
+ok ($args[0] =~ /^Math::BigInt/);
 ok ($args[1],4); ok (ref($args[1]),$args[0]);
 ok ($args[2],5); ok (ref($args[2]),$args[0]);
 ok ($args[3],6); ok (ref($args[3]),'');
@@ -446,6 +486,11 @@ if ($x > $BASE) { ok (1,1) } else { ok ("$x > $BASE","$x < $BASE"); }
 $x = $class->new($MAX); ok ($x->length(), length($MAX));
 
 ###############################################################################
+# test bug that $class->digit($string) did not work
+
+ok ($class->digit(123,2),1);
+
+###############################################################################
 # bug in sub where number with at least 6 trailing zeros after any op failed
 
 $x = $class->new(123456); $z = $class->new(10000); $z *= 10; $x -= $z;
@@ -489,6 +534,25 @@ $x = $class->new('-322056000'); ($x,$y) = $x->bdiv('-12882240');
 
 ok ($y,'0'); is_valid($y);     # $y not '-0'
 
+###############################################################################
+# bug in $x->bmod($y) if $x < 0 and $y > 0
+
+$x = $class->new('-629'); ok ($x->bmod(5033),4404);
+
+###############################################################################
+# bone/binf etc as plain calls (Lite failed them)
+
+ok ($class->bzero(),0);
+ok ($class->bone(),1);
+ok ($class->bone('+'),1);
+ok ($class->bone('-'),-1);
+ok ($class->bnan(),'NaN');
+ok ($class->binf(),'inf');
+ok ($class->binf('+'),'inf');
+ok ($class->binf('-'),'-inf');
+ok ($class->binf('-inf'),'-inf');
+
+###############################################################################
 # all tests done
 
 1;
@@ -514,15 +578,20 @@ sub is_valid
   my ($x,$f) = @_;
 
   my $e = 0;                   # error?
-  # ok as reference? 
-  $e = 'Not a reference to Math::BigInt' if !ref($x);
 
-  # has ok sign?
-  $e = "Illegal sign $x->{sign} (expected: '+', '-', '-inf', '+inf' or 'NaN'"
-   if $e eq '0' && $x->{sign} !~ /^(\+|-|\+inf|-inf|NaN)$/;
+  # allow the check to pass for all Lite, and all MBI and subclasses
+  # ok as reference? 
+  $e = 'Not a reference to Math::BigInt' if ref($x) !~ /^Math::BigInt/;
 
-  $e = "-0 is invalid!" if $e ne '0' && $x->{sign} eq '-' && $x == 0;
-  $e = $CALC->_check($x->{value}) if $e eq '0';
+  if (ref($x) ne 'Math::BigInt::Lite')
+    {
+    # has ok sign?
+    $e = "Illegal sign $x->{sign} (expected: '+', '-', '-inf', '+inf' or 'NaN'"
+     if $e eq '0' && $x->{sign} !~ /^(\+|-|\+inf|-inf|NaN)$/;
+  
+    $e = "-0 is invalid!" if $e ne '0' && $x->{sign} eq '-' && $x == 0;
+    $e = $CALC->_check($x->{value}) if $e eq '0';
+    }
 
   # test done, see if error did crop up
   ok (1,1), return if ($e eq '0');
@@ -545,6 +614,7 @@ __DATA__
 &%=
 100:3:1
 8:9:8
+-629:5033:4404
 &/=
 100:3:33
 -8:2:-4
@@ -755,6 +825,21 @@ E23:NaN
 1e2e3:NaN
 1e2r:NaN
 1e2.0:NaN
+# bug with two '.' in number beeing valid
+1.2.2:NaN
+1.2.3e1:NaN
+-1.2.3:NaN
+-1.2.3e-4:NaN
+1.2e3.4:NaN
+1.2e-3.4:NaN
+1.2.3.4:NaN
+1.2.t:NaN
+1..2:NaN
+1..2e1:NaN
+1..2e1..1:NaN
+12e1..1:NaN
+..2:NaN
+.-2:NaN
 # leading zeros
 012:12
 0123:123
@@ -836,6 +921,10 @@ NaN::0
 +inf:+:1
 -inf:-:1
 -inf:+:0
+-inf:-inf:1
+-inf:+inf:0
++inf:-inf:0
++inf:+inf:1
 # it must be exactly /^[+-]inf$/
 +infinity::0
 -infinity::0
@@ -1024,6 +1113,26 @@ baddNaN:+inf:NaN
 -123456789:987654321:864197532
 -123456789:-987654321:-1111111110
 +123456789:-987654321:-864197532
+-1:10001:10000
+-1:100001:100000
+-1:1000001:1000000
+-1:10000001:10000000
+-1:100000001:100000000
+-1:1000000001:1000000000
+-1:10000000001:10000000000
+-1:100000000001:100000000000
+-1:1000000000001:1000000000000
+-1:10000000000001:10000000000000
+-1:-10001:-10002
+-1:-100001:-100002
+-1:-1000001:-1000002
+-1:-10000001:-10000002
+-1:-100000001:-100000002
+-1:-1000000001:-1000000002
+-1:-10000000001:-10000000002
+-1:-100000000001:-100000000002
+-1:-1000000000001:-1000000000002
+-1:-10000000000001:-10000000000002
 &bsub
 abc:abc:NaN
 abc:+0:NaN
@@ -1066,6 +1175,26 @@ abc:+0:NaN
 -123456789:+987654321:-1111111110
 -123456789:-987654321:864197532
 +123456789:-987654321:1111111110
+10001:1:10000
+100001:1:100000
+1000001:1:1000000
+10000001:1:10000000
+100000001:1:100000000
+1000000001:1:1000000000
+10000000001:1:10000000000
+100000000001:1:100000000000
+1000000000001:1:1000000000000
+10000000000001:1:10000000000000
+10001:-1:10002
+100001:-1:100002
+1000001:-1:1000002
+10000001:-1:10000002
+100000001:-1:100000002
+1000000001:-1:1000000002
+10000000001:-1:10000000002
+100000000001:-1:100000000002
+1000000000001:-1:1000000000002
+10000000000001:-1:10000000000002
 &bmul
 abc:abc:NaN
 abc:+0:NaN
@@ -1243,6 +1372,46 @@ inf:0:inf
 14:3:4
 # bug in Calc with '99999' vs $BASE-1
 10000000000000000000000000000000000000000000000000000000000000000000000000000000000:10000000375084540248994272022843165711074:999999962491547381984643365663244474111576
+&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
+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
+&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
 # inf handling, see table in doc
 0:inf:0
@@ -1318,6 +1487,34 @@ abc:1:abc:NaN
 100041000510123:3:0
 152403346:12345:4321
 9:5:4
+# test shortcuts in Calc
+# 1ex % 9 is always == 1, 1ex % 113 is != 1 for x = (4..9), 1ex % 10 = 0
+1234:9:1
+123456:9:3
+12345678:9:0
+1234567891:9:1
+123456789123:9:6
+12345678912345:9:6
+1234567891234567:9:1
+123456789123456789:9:0
+1234:10:4
+123456:10:6
+12345678:10:8
+1234567891:10:1
+123456789123:10:3
+12345678912345:10:5
+1234567891234567:10:7
+123456789123456789:10:9
+1234:113:104
+123456:113:60
+12345678:113:89
+1234567891:113:64
+123456789123:113:95
+12345678912345:113:53
+1234567891234567:113:56
+123456789123456789:113:39
+# bug in bmod() not modifying the variable in place
+-629:5033:4404
 &bgcd
 abc:abc:NaN
 abc:+0:NaN
@@ -1762,6 +1959,7 @@ NaNas_hex:NaN
 -0:0b0
 1:0b1
 0b1010111101010101010110110110110110101:0b1010111101010101010110110110110110101
+0x123456789123456789:0b100100011010001010110011110001001000100100011010001010110011110001001
 +inf:inf
 -inf:-inf
 NaNas_bin:NaN