#!perl
use strict;
use warnings;
use Data::Dumper;
use Math::GMP;
use Test::More;
use Config;
my ($f);
my @data = <DATA>;
my @tests = grep { ! /\A&/ } @data;
plan tests => (2 * @tests + 10);
my $WITH_FEATURE = ("$]" >= 5.022);
# work around Test::Builder bug if needed
monkey_patch() if $Test::More::VERSION < 1.302189;
LINES:
foreach my $line (@data) {
chomp $line;
if ($line =~ s/\A&//) {
$f = $line;
next LINES;
}
my @args = split(/:/,$line,99);
my $ans = pop(@args);
my $expect_list = 0;
my $ans_any = ($ans =~ s/\AANY//);
if ($ans_any) {
$ans = [ split /,/, $ans ];
}
elsif ($ans =~ s/\AL//) {
$ans = [ split /,/, $ans ];
$expect_list = 1;
}
my $first_arg = $args[0];
my $try = ( ( $first_arg =~ /\Ai([-+]?[0-9]+)\z/ ) ? "\$x = $1;"
: ( $first_arg =~ /\Ab([-+]?.+),([0-9]+)\z/ ) ? qq#\$x = Math::GMP->new("$1", $2);#
: qq#\$x = Math::GMP->new("$first_arg");# );
if ($f eq 'bnorm') {
$try .= '$x+0;';
}
elsif ($f eq 'fibonacci') {
$try .= 'Math::GMP::fibonacci($x);';
}
elsif ($f eq 'bfac') {
$try .= '$x->bfac();';
}
elsif ($f eq 'bneg') {
$try .= '-$x;';
}
elsif ($f eq 'babs') {
$try .= 'abs $x;';
}
elsif ($f eq 'square_root') {
$try .= 'Math::GMP::bsqrt($x);';
}
elsif ($f eq 'square_rootrem') {
$try .= '[ Math::GMP::bsqrtrem($x) ];';
}
elsif ($f eq 'perfect_power') {
$try .= '$x->is_perfect_power';
}
elsif ($f eq 'perfect_square') {
$try .= '$x->is_perfect_square';
}
elsif ($f eq 'uintify') {
$try .= 'Math::GMP::uintify($x);';
$ans = pop(@args) if ($Config{longsize} == 4 && scalar @args > 1);
}
elsif ($f eq 'intify') {
$try .= 'Math::GMP::intify($x);';
$ans = pop(@args) if ($Config{longsize} == 4 && scalar @args > 1);
}
elsif ($f eq 'probab_prime') {
my $rets = $args[1];
$try .= "Math::GMP::probab_prime(\$x,$rets);";
}
elsif ($f eq 'new_from_base') {
$try .= '$x;';
}
else {
if ( $args[1] =~ /\Ai([-+]?[0-9]+)\z/ ) {
$try .= "\$y = $1;";
}
elsif ( $args[1] =~ /\Af([-+]?[0-9.]+)\z/ ) {
$try .= "\$y = $1;";
}
else {
$try .= qq#\$y = Math::GMP->new("$args[1]");#;
}
if ($f eq 'bcmp') {
$try .= '$x <=> $y;';
}
elsif ($f eq 'band') {
$try .= '$x & $y;';
}
elsif ($f eq 'bxor') {
$try .= '$x ^ $y;';
}
elsif ($f eq 'bior') {
$try .= '$x | $y;';
}
elsif ($f eq 'blshift') {
$try .= '$x << $y;';
}
elsif ($f eq 'brshift') {
$try .= '$x >> $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 'bmulf') {
$try .= 'Math::GMP::bmulf($x,$y)';
}
elsif ($f eq 'bdiv') {
$try .= '$x / $y;';
}
elsif ($f eq 'bmod') {
$try .= '$x % $y;';
}
elsif ($f eq 'bdiv2a') {
$try .= '((Math::GMP::bdiv($x, $y))[0]);';
}
elsif ($f eq 'bdiv2b') {
$try .= '((Math::GMP::bdiv($x, $y))[1]);';
}
elsif ($f eq 'bgcd') {
$try .= 'Math::GMP::bgcd($x, $y);';
}
elsif ($f eq 'gcd') {
$try .= 'Math::GMP::gcd($x, $y);';
}
elsif ($f eq 'blcm') {
$try .= 'Math::GMP::blcm($x, $y);';
}
elsif ($f eq 'bmodinv') {
$try .= 'Math::GMP::bmodinv($x, $y);';
}
elsif ($f eq 'bnok') {
$try .= 'Math::GMP::bnok($x, $y);';
}
elsif ($f eq 'sizeinbase') {
$try .= 'Math::GMP::sizeinbase_gmp($x, $y);';
}
elsif ($f eq 'add_ui') {
$try .= 'Math::GMP::add_ui_gmp($x, $y); $x';
}
elsif ($f eq 'mul_2exp') {
$try .= 'Math::GMP::mul_2exp_gmp($x, $y);';
}
elsif ($f eq 'div_2exp') {
$try .= 'Math::GMP::div_2exp_gmp($x, $y);';
}
elsif ($f eq 'mmod') {
$try .= 'Math::GMP::mmod_gmp($x, $y);';
}
elsif ($f eq 'mod_2exp') {
$try .= 'Math::GMP::mod_2exp_gmp($x, $y);';
}
elsif ($f eq 'legendre') {
$try .= 'Math::GMP::legendre($x, $y);';
}
elsif ($f eq 'jacobi') {
$try .= 'Math::GMP::jacobi($x, $y);';
}
elsif ($f eq 'test_bit') {
$try .= 'Math::GMP::gmp_tstbit($x, $y);';
}
elsif ($f eq 'root') {
$try .= '$x->broot($y)';
}
elsif ($f eq 'rootrem') {
$try .= '[ $x->brootrem($y) ]';
}
else {
if ( $args[2] =~ /\Ai([-+]?[0-9]+)\z/ ) {
$try .= "\$z = $1;";
}
else {
$try .= qq#\$z = Math::GMP->new("$args[2]");#;
}
if ($f eq 'powm') {
$try .= 'Math::GMP::powm_gmp($x, $y, $z);';
}
else {
warn 'Unknown op';
}
}
}
my ($x,$y,$z);
my $got = eval $try;
my $test_sub = sub {
my $desc = shift;
my $blurb = "Test worked ${desc}: $try";
if ($ans_any) {
ok(scalar(1 == scalar(grep { $_ eq $got } @$ans)), $blurb);
} elsif ($expect_list) {
is_deeply($got, $ans, $blurb);
} else {
is("$got", $ans, $blurb);
}
};
$test_sub->("");
if ($WITH_FEATURE)
{
$got = eval "use feature 'bitwise'; no warnings 'experimental::bitwise'; $try";
$test_sub->("[feature bitwise]");
}
else
{
pass("skipped due to feature");
}
}
# Test of bfac as described in the pod
{
my $x = Math::GMP->new(5);
my $val = $x->bfac();
is(int $val, 120, 'gfac gives expected result');
}
# some assorted tests for internal functions
{
my $x = Math::GMP->new('123');
my $y = Math::GMP::gmp_copy($x);
is (ref($y),ref($x), 'refs are the same');
is ("$y",'123', 'gmp_copy gives correct value');
}
{
# boolean check should not fall back to truncating intify
my $s = '1' . ('0' x 70);
my $i1 = Math::GMP->new($s);
is ($s, "$i1", 'new 1e70 from string is preserved');
my $bool = $i1 ? 1 : 0;
is ($bool, 1, '1e70 is boolean TRUE');
my $i2 = Math::GMP->new($i1); # has internal boolean check
is ($s, "$i2", 'new 1e70 from object is preserved');
}
{
# Test of blshift as described in the POD.
my $x = Math::GMP->new('2');
my $result = $x->blshift(4, 0);
is ("$x", '2', 'x stays the same.');
is ("$result", '32', 'Result is 2 << 4');
}
{
# Test of brshift as described in the POD.
my $x = Math::GMP->new('5');
my $result = $x->brshift(1, 0);
is ("$x", '5', 'x stays the same.');
is ("$result", '2', 'Result is 2 << 4');
}
# all done
#
# Until v1.302189, Test::Builder::_unoverload() tries to invoke
# an overload method wrongly. We try it here, and if it fails we monkey
# patch it to a version that should work.
#
sub monkey_patch {
my $tb = Test::Builder->new;
my $z = Math::GMP->new(17);
eval { $tb->_unoverload(q{""}, \$z) };
# do nothing if it worked: $z should have been replaced with its string
return if !$@ && $z eq '17' && !ref($z);
# patch if it failed
use Scalar::Util qw{ blessed };
no warnings qw{ redefine };
*Test::Builder::_unoverload = sub {
my ($self, $type, $thing) = @_;
return unless ref $$thing;
return unless blessed($$thing) || scalar $self->_try(sub{ $$thing->isa('UNIVERSAL') });
{
local ($!, $@);
require overload;
}
my $string_meth = overload::Method( $$thing, $type ) || return;
# this is the fix - the interface requires two args passed in
#$$thing = $$thing->$string_meth();
$$thing = $$thing->$string_meth(undef, 0);
};
return;
}
__END__
&bcmp
+0:0:0
-1:0:-1
+0:-1:1
+1:0:1
+0:1:-1
-1:1:-1
+1:-1:1
-1:-1:0
+1:1:0
+123:123:0
+123:12:1
+12:123:-1
-123:-123:0
-123:-12:-1
-12:-123:1
+123:124:-1
+124:123:1
-123:-124:1
-124:-123:-1
+100:5:1
i+100:5:1
+100:i5:1
i-10:-10:0
&badd
+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
i+9999999:1:10000000
+99999999:1:100000000
+999999999:1:1000000000
+9999999999:1:10000000000
+99999999999:1:100000000000
+99999999999:i1: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
&bsub
+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
+99999999999:i1: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
i4:12345678987:-12345678983
&bmul
+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
+11111111111:i9:99999999999
i9:+11111111111: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
&bmulf
+0:f0.0:0
+0:f1.0:0
+1:f0.0:0
+0:f-1.0:0
-1:f0.0:0
+123456789123456789:f0.0:0
+0:f123456789123456789.0:0
-1:f-1.0:1
-1:f1.0:-1
+1:f-1.0:-1
+1:f1.0:1
+2:f3.0:6
-2:f3.0:-6
+2:f-3.0:-6
-2:f-3.0:6
+1:f+1.5:1
-1:f+1.5:-1
+1:f-1.5:-1
-1:f-1.0:1
+100000000000000000001:f+1.5:150000000000000000001
-100000000000000000001:f+1.5:-150000000000000000001
+100000000000000000001:f-1.5:-150000000000000000001
-100000000000000000001:f-1.5:150000000000000000001
&bdiv2a
+0:1:0
+0:-1:0
+1:1:1
-1:-1:1
+1:-1:-1
-1:1:-1
+1:2:0
+2:1:2
+1000000000:9:111111111
+1000000000:i9:111111111
+2000000000:9:222222222
+3000000000:9:333333333
+4000000000:9:444444444
+5000000000:9:555555555
+6000000000:9:666666666
+7000000000:9:777777777
+8000000000:9:888888888
+9000000000:9:1000000000
+35500000:113:314159
+71000000:226:314159
+106500000:339:314159
+1000000000:3:333333333
+10:5:2
+100:4:25
+1000:8:125
+10000:16:625
i+10000:16:625
+999999999999:9:111111111111
+999999999999:99:10101010101
+999999999999:999:1001001001
+999999999999:9999:100010001
+999999999999999:99999:10000100001
&bdiv
+0:1:0
+0:-1:0
+1:1:1
-1:-1:1
+1:-1:-1
-1:1:-1
+1:2:0
+2:1:2
+1000000000:9:111111111
+1000000000:i9:111111111
+2000000000:9:222222222
+3000000000:9:333333333
+4000000000:9:444444444
+5000000000:9:555555555
+6000000000:9:666666666
+7000000000:9:777777777
+8000000000:9:888888888
+9000000000:9:1000000000
+35500000:113:314159
+71000000:226:314159
+106500000:339:314159
+1000000000:3:333333333
+10:5:2
+100:4:25
+1000:8:125
+10000:16:625
i+10000:16:625
+999999999999:9:111111111111
+999999999999:99:10101010101
+999999999999:999:1001001001
+999999999999:9999:100010001
+999999999999999:99999:10000100001
&bdiv2b
+0:1:0
+0:-1:0
+1:1:0
-1:-1:0
+1:-1:0
-1:1:0
+1:2:1
+2:1:0
+1000000000:9:1
+1000000000:i9:1
+2000000000:9:2
+3000000000:9:3
+4000000000:9:4
+5000000000:9:5
+6000000000:9:6
+7000000000:9:7
+8000000000:9:8
+9000000000:9:0
+35500000:113:33
i+35500000:113:33
+71000000:226:66
+106500000:339:99
+1000000000:3:1
+10:5:0
+100:4:0
+1000:8:0
+10000:16:0
+999999999999:9:0
+999999999999:99:0
+999999999999:999:0
+999999999999:9999:0
+999999999999999:99999:0
&bmod
+0:1:0
+0:-1:0
+1:1:0
-1:-1:0
+1:-1:0
-1:1:0
+1:2:1
+2:1:0
+1000000000:9:1
+1000000000:i9:1
+2000000000:9:2
+3000000000:9:3
+4000000000:9:4
+5000000000:9:5
+6000000000:9:6
+7000000000:9:7
+8000000000:9:8
+9000000000:9:0
+35500000:113:33
i+35500000:113:33
+71000000:226:66
+106500000:339:99
+1000000000:3:1
+10:5:0
+100:4:0
+1000:8:0
+10000:16:0
+999999999999:9:0
+999999999999:99:0
+999999999999:999:0
+999999999999:9999:0
+999999999999999:99999:0
&bgcd
+0:0:0
+0:1:1
+1:0:1
+1:1:1
+2:3:1
+3:2:1
+100:625:25
+4096:81:1
&gcd
+0:0:0
+0:1:1
+1:0:1
+1:1:1
+2:3:1
+3:2:1
+100:625:25
+4096:81:1
&blcm
+0:0:0
+0:1:0
+1:0:0
+1:1:1
+2:3:6
+3:2:6
+100:625:2500
+75600:5402250:129654000
&bmodinv
+0:1:0
+1:1:0
+2:3:2
+5:7:3
+999:1000:999
&new_from_base
0xff:255
0x2395fa:2332154
babcdefgh,36:808334348993
&sizeinbase
+5:i10:1
+9999999999:i16:9
-5000:i2:13
&uintify
+15:15
+9999999999:1410065407:9999999999
+99999999999:1215752191:99999999999
+999999999999:3567587327:999999999999
&add_ui
+999999:i1:1000000
+9999999:i1:10000000
+99999999:i1:100000000
&intify
+999999999:999999999
+9999999999:1410065407:9999999999
&mul_2exp
+9999:i9:5119488
+99999:i9:51199488
+0:i1:0
+1:i0:1
&div_2exp
+999999:i1111:0
+0:i1:0
&powm
+99999:999999:99:27
+1:1:1:0
+1:0:1:0
&mmod
+99999:100002:99999
+1:1:0
&mod_2exp
+99999999:11111:99999999
+0:1:0
&jacobi
+1:15:1
+1:15:1
+2:15:1
+3:15:0
+4:15:1
+5:15:0
+6:15:0
+7:15:-1
+8:15:1
+9:15:0
+10:15:0
+11:15:-1
+12:15:0
+13:15:-1
+14:15:-1
+15:15:0
&band
7:3:3
2:3:2
4:1:0
&bxor
7:3:4
2:3:1
4:1:5
&bior
7:3:7
2:3:3
4:1:5
&bfac
1:1
2:2
3:6
4:24
5:120
6:720
&fibonacci
2:1
3:2
4:3
5:5
6:8
7:13
8:21
9:34
10:55
&test_bit
10:0:0
1:0:1
3:1:1
3:2:0
&root
16:i2:4
16:i4:2
999:i3:9
-1:i3:-1
-2:i3:-1
&rootrem
16:i2:L4,0
999:i3:L9,270
-2:i3:L-1,-1
&square_root
16:4
1:1
0:0
100:10
101:10
99:9
&square_rootrem
16:L4,0
100:L10,0
101:L10,1
99:L9,18
0:L0,0
&perfect_power
99:0
100:1
101:0
0:1
-27:1
-9:0
&perfect_square
99:0
100:1
101:0
0:1
-27:0
-9:0
&probab_prime
5:10:2
6:10:0
&gcd
0:0:0
1:0:1
9:9:9
17:19:1
54:24:6
42:56:14
9:28:1
48:180:12
i48:i180:12
-30:-90:30
-3:-9:3
i-3:i-9:3
2705353758:2540073744:18
i2705353758:i2540073744:18
12848174105599691600:15386870946739346600:1400
9785375481451202685:17905669244643674637:117
921166566073002915606255698642:1168315374100658224561074758384:14
1214969109355385138343690512057521757303400673155500334102084:1112036111724848964580068879654799564977409491290450115714228:42996
745845206184162095041321:61540282492897317017092677682588744425929751009997907259657808323805386381007:1
&blcm
i1:i0:0
i0:i1:0
i17:i19:323
i54:i24:216
i36:i45:180
i-36:i-45:180
i-36:i-45:180
i36:i-45:180
i-36:i45:180
i3219664501:i2880273383:9273513964420276883
9999999998987:10000000001011:99999999999979999998975857
892478777297173184633:892478777297173184633:892478777297173184633
&jacobi
i109981:i737777:1
i737779:i121080:-1
i-737779:i121080:1
i737779:i-121080:-1
i-737779:i-121080:-1
i12345:i331:-1
i1001:i9907:-1
i19:i45:1
i8:i21:-1
i5:i21:1
i5:i1237:-1
i10:i49:1
i123:i4567:-1
i3:i18:0
i3:i-18:0
i-2:i0:0
i-1:i0:1
i0:i0:0
i1:i0:1
i2:i0:0
i-2:i1:1
i-1:i1:1
i0:i1:1
i1:i1:1
i2:i1:1
i-2:i-1:-1
i-1:i-1:-1
i0:i-1:1
i1:i-1:1
i2:i-1:1
i3686556869:i428192857:1
i-1453096827:i364435739:-1
i3527710253:i-306243569:1
i-1843526669:i-332265377:1
i321781679:i4095783323:-1
i454249403:i-79475159:-1
17483840153492293897:455592493:1
-1402663995299718225:391125073:1
16715440823750591903:-534621209:-1
13106964391619451641:16744199040925208803:1
11172354269896048081:10442187294190042188:-1
-5694706465843977004:9365273357682496999:-1
878944444444444447324234:216539985579699669610468715172511426009:-1
&probab_prime
3878888047:25:ANY1,2
14811094489161957443:25:1
232959001450513754379792189108873634181:25:1
91824020991616815553147615676933454480045241423098328989602116468298297311309:25:1
8285396061339403252920302070391390891474883409843237347887428315444504156793935159055430946705757466964822392797379161103939327123077267166338215317904079:25:1
777777777777777777777777:25:0
890745785790123461234805903467891234681234:25:0
8041390271962017234692123621666121818392263837471332893549490730885083462618835990190315107479962729421426370683173686420981834217178353304525610906493143:25:0
1498370845232252488162599227507794675135574818583361091623468615853723670176324198216325177:25:0
2887148238050771212671429597130393991977609459279722700926516024197432303799152733116328983144639225941977803110929349655578418949441740933805615113979999421542416933972905423711002751042080134966731755152859226962916775325475044445856101949404200039904432116776619949629539250452698719329070373564032273701278453899126120309244841494728976885406024976768122077071687938121709811322297802059565867:25:0
&blshift
0:0:0
1:0:1
2:640:9124881235244390437282343211400582649786457014497119861158385035798550334417354773011825622634742799557284619147188814621377409442750875996505322639444428376503989348720529900165748384493207552
100:524:5491838128104487771985520639265114573815548240114644327515570767348434546718124841698047712529163643981837049113184686429697590399773315050059222632892045721600
&brshift
0:0:0
1:0:1
9124881235244390437282343211400582649786457014497119861158385035798550334417354773011825622634742799557284619147188814621377409442750875996505322639444428376503989348720529900165748384493207552:640:2
5491838128104487771985520639265114573815548240114644327515570767348434546718124841698047712529163643981837049113184686429697590399773315050059222632892045721600:524:100
50:1:25
3:1:1
&bnok
5:2:10
500:250:116744315788277682920934734762176619659230081180311446124100284957811112673608473715666417775521605376810865902709989580160037468226393900042796872256
67:23:530707489338171600