diff options
author | Neil Bowers <neilb@neilb.org> | 2021-07-22 21:14:26 +0100 |
---|---|---|
committer | Neil Bowers <neilb@neilb.org> | 2021-07-22 21:14:26 +0100 |
commit | 7deec013f46126144fe21a38992ada81a83382aa (patch) | |
tree | 842b285af196a575f4ea56bb43f6ff86722cc234 | |
parent | a8769738d281c6b57a291bd3f605e304ec825799 (diff) | |
download | perl-7deec013f46126144fe21a38992ada81a83382aa.tar.gz |
Upgraded Math::BigRat, Math::BigInt::FastCalc, Math::BigInt, & bignum
They have interdependencies that require at least these versions,
so needed to be added together.
65 files changed, 6844 insertions, 1802 deletions
@@ -1322,6 +1322,7 @@ cpan/Math-BigInt/t/big_pi_e.t test bpi() and bexp() cpan/Math-BigInt/t/bigfltpm.inc Shared tests for bigfltpm.t and sub_mbf.t cpan/Math-BigInt/t/bigfltpm.t See if BigFloat.pm works cpan/Math-BigInt/t/bigintc.t See if BigInt/Calc.pm works +cpan/Math-BigInt/t/bigintc-import.t cpan/Math-BigInt/t/bigintpm.inc Shared tests for bigintpm.t and sub_mbi.t cpan/Math-BigInt/t/bigintpm.t See if BigInt.pm works cpan/Math-BigInt/t/bigints.t See if BigInt.pm works @@ -1347,6 +1348,7 @@ cpan/Math-BigInt/t/dparts-mbi.t Test Math::BigInt cpan/Math-BigInt/t/eparts-mbf.t Test Math::BigInt cpan/Math-BigInt/t/eparts-mbi.t Test Math::BigInt cpan/Math-BigInt/t/from_base-mbi.t +cpan/Math-BigInt/t/from_base_num-mbi.t cpan/Math-BigInt/t/from_bin-mbf.t Test Math::BigInt cpan/Math-BigInt/t/from_bin-mbi.t cpan/Math-BigInt/t/from_hex-mbf.t Test Math::BigInt @@ -1391,6 +1393,7 @@ cpan/Math-BigInt/t/sub_mbf.t Empty subclass test of BigFloat cpan/Math-BigInt/t/sub_mbi.t Empty subclass test of BigInt cpan/Math-BigInt/t/sub_mif.t Test A & P with subclasses using mbimbf.inc cpan/Math-BigInt/t/to_base-mbi.t +cpan/Math-BigInt/t/to_base_num-mbi.t cpan/Math-BigInt/t/to_ieee754-mbf.t Test Math::BigInt cpan/Math-BigInt/t/trap.t Test whether trap_nan and trap_inf work cpan/Math-BigInt/t/upgrade.inc Actual tests for upgrade.t @@ -1402,9 +1405,19 @@ cpan/Math-BigInt/t/use_lib1.t Test combinations of Math::BigInt and BigFloat cpan/Math-BigInt/t/use_lib2.t Test combinations of Math::BigInt and BigFloat cpan/Math-BigInt/t/use_lib3.t Test combinations of Math::BigInt and BigFloat cpan/Math-BigInt/t/use_lib4.t Test combinations of Math::BigInt and BigFloat +cpan/Math-BigInt/t/use_lib5.t +cpan/Math-BigInt/t/use_lib6.t cpan/Math-BigInt/t/use_mbfw.t use BigFloat w/ with and lib at the same time cpan/Math-BigInt/t/with_sub.t Test use Math::BigFloat with => package cpan/Math-BigInt-FastCalc/FastCalc.xs Math::BigInt::FastCalc extension +cpan/Math-BigInt-FastCalc/inc/Module/Install.pm +cpan/Math-BigInt-FastCalc/inc/Module/Install/Base.pm +cpan/Math-BigInt-FastCalc/inc/Module/Install/Can.pm +cpan/Math-BigInt-FastCalc/inc/Module/Install/Fetch.pm +cpan/Math-BigInt-FastCalc/inc/Module/Install/Makefile.pm +cpan/Math-BigInt-FastCalc/inc/Module/Install/Metadata.pm +cpan/Math-BigInt-FastCalc/inc/Module/Install/Win32.pm +cpan/Math-BigInt-FastCalc/inc/Module/Install/WriteAll.pm cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm Math::BigInt::FastCalc extension cpan/Math-BigInt-FastCalc/t/bigintfc.t Math::BigInt::FastCalc extension cpan/Math-BigInt-FastCalc/t/biglog.t @@ -1421,8 +1434,10 @@ cpan/Math-BigRat/t/bigratpm.inc Math::BigRat test cpan/Math-BigRat/t/bigratpm.t Math::BigRat test cpan/Math-BigRat/t/bigratup.t test under $Math::BigInt::upgrade cpan/Math-BigRat/t/bitwise.t Math::BigRat test +cpan/Math-BigRat/t/bnok-mbr.t cpan/Math-BigRat/t/hang.t Math::BigRat test for bug #34584 - hang in exp() cpan/Math-BigRat/t/Math/BigRat/Test.pm Math::BigRat test helper +cpan/Math-BigRat/t/new-mbr.t cpan/Math-BigRat/t/requirer.t see if require works properly cpan/Math-BigRat/t/rt121139.t cpan/Math-BigRat/t/trap.t see if trap_nan and trap_inf work diff --git a/Makefile.SH b/Makefile.SH index 0033a0e145..4eeac8f0e6 100755 --- a/Makefile.SH +++ b/Makefile.SH @@ -1430,13 +1430,14 @@ _cleaner2: -rmdir ext/B/lib -rm -f dist/Time-HiRes/xdefine rm -f so_locations $(LIBPERL_NONSHR) $(MINIPERL_NONSHR) - -rmdir lib/version lib/threads lib/inc/ExtUtils lib/inc lib/encoding - -rmdir lib/autodie/exception lib/autodie/Scope lib/autodie lib/XS - -rmdir lib/Win32API lib/VMS lib/Unicode/Collate/Locale - -rmdir lib/Unicode/Collate/CJK lib/Unicode/Collate lib/Tie/Hash - -rmdir lib/Thread lib/Text lib/Test2/Util lib/Test2/Tools - -rmdir lib/Test2/IPC/Driver lib/Test2/IPC lib/Test2/Hub/Interceptor - -rmdir lib/Test2/Hub lib/Test2/Formatter lib/Test2/EventFacet/Info + -rmdir lib/version lib/threads lib/inc/Module/Install lib/inc/Module + -rmdir lib/inc/ExtUtils lib/inc lib/encoding lib/autodie/exception + -rmdir lib/autodie/Scope lib/autodie lib/XS lib/Win32API lib/VMS + -rmdir lib/Unicode/Collate/Locale lib/Unicode/Collate/CJK + -rmdir lib/Unicode/Collate lib/Tie/Hash lib/Thread lib/Text + -rmdir lib/Test2/Util lib/Test2/Tools lib/Test2/IPC/Driver + -rmdir lib/Test2/IPC lib/Test2/Hub/Interceptor lib/Test2/Hub + -rmdir lib/Test2/Formatter lib/Test2/EventFacet/Info -rmdir lib/Test2/EventFacet lib/Test2/Event/TAP lib/Test2/Event -rmdir lib/Test2/API/InterceptResult lib/Test2/API lib/Test2 -rmdir lib/Test/use lib/Test/Tester lib/Test/Builder/Tester diff --git a/Porting/Maintainers.pl b/Porting/Maintainers.pl index f2e98c10a5..b12c7f20e7 100755 --- a/Porting/Maintainers.pl +++ b/Porting/Maintainers.pl @@ -182,9 +182,10 @@ use File::Glob qw(:case); }, 'bignum' => { - 'DISTRIBUTION' => 'PJACKLAM/bignum-0.51.tar.gz', + 'DISTRIBUTION' => 'PJACKLAM/bignum-0.53.tar.gz', 'FILES' => q[cpan/bignum], 'EXCLUDED' => [ + qr{^xt/}, qr{^t/author-}, qr{^t/release-}, qw( t/00sig.t @@ -721,9 +722,10 @@ use File::Glob qw(:case); }, 'Math::BigInt' => { - 'DISTRIBUTION' => 'PJACKLAM/Math-BigInt-1.999818.tar.gz', + 'DISTRIBUTION' => 'PJACKLAM/Math-BigInt-1.999823.tar.gz', 'FILES' => q[cpan/Math-BigInt], 'EXCLUDED' => [ + qr{^xt/}, qr{^examples/}, qr{^t/author-}, qr{^t/release-}, @@ -734,9 +736,10 @@ use File::Glob qw(:case); }, 'Math::BigInt::FastCalc' => { - 'DISTRIBUTION' => 'PJACKLAM/Math-BigInt-FastCalc-0.5009.tar.gz', + 'DISTRIBUTION' => 'PJACKLAM/Math-BigInt-FastCalc-0.5010.tar.gz', 'FILES' => q[cpan/Math-BigInt-FastCalc], 'EXCLUDED' => [ + qr{^xt/}, qr{^t/author-}, qr{^t/release-}, qr{^t/Math/BigInt/Lib/TestUtil.pm}, @@ -757,9 +760,11 @@ use File::Glob qw(:case); }, 'Math::BigRat' => { - 'DISTRIBUTION' => 'PJACKLAM/Math-BigRat-0.2614.tar.gz', + 'DISTRIBUTION' => 'PJACKLAM/Math-BigRat-0.2617.tar.gz', 'FILES' => q[cpan/Math-BigRat], 'EXCLUDED' => [ + qr{^xt/}, + qr{^math-bigrat-pod.diff}, qr{^t/author-}, qr{^t/release-}, qw( t/00sig.t diff --git a/cpan/Math-BigInt-FastCalc/inc/Module/Install.pm b/cpan/Math-BigInt-FastCalc/inc/Module/Install.pm new file mode 100644 index 0000000000..74caf9c189 --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/inc/Module/Install.pm @@ -0,0 +1,470 @@ +#line 1 +package Module::Install; + +# For any maintainers: +# The load order for Module::Install is a bit magic. +# It goes something like this... +# +# IF ( host has Module::Install installed, creating author mode ) { +# 1. Makefile.PL calls "use inc::Module::Install" +# 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install +# 3. The installed version of inc::Module::Install loads +# 4. inc::Module::Install calls "require Module::Install" +# 5. The ./inc/ version of Module::Install loads +# } ELSE { +# 1. Makefile.PL calls "use inc::Module::Install" +# 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install +# 3. The ./inc/ version of Module::Install loads +# } + +use 5.005; +use strict 'vars'; +use Cwd (); +use File::Find (); +use File::Path (); + +use vars qw{$VERSION $MAIN}; +BEGIN { + # All Module::Install core packages now require synchronised versions. + # This will be used to ensure we don't accidentally load old or + # different versions of modules. + # This is not enforced yet, but will be some time in the next few + # releases once we can make sure it won't clash with custom + # Module::Install extensions. + $VERSION = '1.01'; + + # Storage for the pseudo-singleton + $MAIN = undef; + + *inc::Module::Install::VERSION = *VERSION; + @inc::Module::Install::ISA = __PACKAGE__; + +} + +sub import { + my $class = shift; + my $self = $class->new(@_); + my $who = $self->_caller; + + #------------------------------------------------------------- + # all of the following checks should be included in import(), + # to allow "eval 'require Module::Install; 1' to test + # installation of Module::Install. (RT #51267) + #------------------------------------------------------------- + + # Whether or not inc::Module::Install is actually loaded, the + # $INC{inc/Module/Install.pm} is what will still get set as long as + # the caller loaded module this in the documented manner. + # If not set, the caller may NOT have loaded the bundled version, and thus + # they may not have a MI version that works with the Makefile.PL. This would + # result in false errors or unexpected behaviour. And we don't want that. + my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm'; + unless ( $INC{$file} ) { die <<"END_DIE" } + +Please invoke ${\__PACKAGE__} with: + + use inc::${\__PACKAGE__}; + +not: + + use ${\__PACKAGE__}; + +END_DIE + + # This reportedly fixes a rare Win32 UTC file time issue, but + # as this is a non-cross-platform XS module not in the core, + # we shouldn't really depend on it. See RT #24194 for detail. + # (Also, this module only supports Perl 5.6 and above). + eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006; + + # If the script that is loading Module::Install is from the future, + # then make will detect this and cause it to re-run over and over + # again. This is bad. Rather than taking action to touch it (which + # is unreliable on some platforms and requires write permissions) + # for now we should catch this and refuse to run. + if ( -f $0 ) { + my $s = (stat($0))[9]; + + # If the modification time is only slightly in the future, + # sleep briefly to remove the problem. + my $a = $s - time; + if ( $a > 0 and $a < 5 ) { sleep 5 } + + # Too far in the future, throw an error. + my $t = time; + if ( $s > $t ) { die <<"END_DIE" } + +Your installer $0 has a modification time in the future ($s > $t). + +This is known to create infinite loops in make. + +Please correct this, then run $0 again. + +END_DIE + } + + + # Build.PL was formerly supported, but no longer is due to excessive + # difficulty in implementing every single feature twice. + if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" } + +Module::Install no longer supports Build.PL. + +It was impossible to maintain duel backends, and has been deprecated. + +Please remove all Build.PL files and only use the Makefile.PL installer. + +END_DIE + + #------------------------------------------------------------- + + # To save some more typing in Module::Install installers, every... + # use inc::Module::Install + # ...also acts as an implicit use strict. + $^H |= strict::bits(qw(refs subs vars)); + + #------------------------------------------------------------- + + unless ( -f $self->{file} ) { + foreach my $key (keys %INC) { + delete $INC{$key} if $key =~ /Module\/Install/; + } + + local $^W; + require "$self->{path}/$self->{dispatch}.pm"; + File::Path::mkpath("$self->{prefix}/$self->{author}"); + $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self ); + $self->{admin}->init; + @_ = ($class, _self => $self); + goto &{"$self->{name}::import"}; + } + + local $^W; + *{"${who}::AUTOLOAD"} = $self->autoload; + $self->preload; + + # Unregister loader and worker packages so subdirs can use them again + delete $INC{'inc/Module/Install.pm'}; + delete $INC{'Module/Install.pm'}; + + # Save to the singleton + $MAIN = $self; + + return 1; +} + +sub autoload { + my $self = shift; + my $who = $self->_caller; + my $cwd = Cwd::cwd(); + my $sym = "${who}::AUTOLOAD"; + $sym->{$cwd} = sub { + my $pwd = Cwd::cwd(); + if ( my $code = $sym->{$pwd} ) { + # Delegate back to parent dirs + goto &$code unless $cwd eq $pwd; + } + unless ($$sym =~ s/([^:]+)$//) { + # XXX: it looks like we can't retrieve the missing function + # via $$sym (usually $main::AUTOLOAD) in this case. + # I'm still wondering if we should slurp Makefile.PL to + # get some context or not ... + my ($package, $file, $line) = caller; + die <<"EOT"; +Unknown function is found at $file line $line. +Execution of $file aborted due to runtime errors. + +If you're a contributor to a project, you may need to install +some Module::Install extensions from CPAN (or other repository). +If you're a user of a module, please contact the author. +EOT + } + my $method = $1; + if ( uc($method) eq $method ) { + # Do nothing + return; + } elsif ( $method =~ /^_/ and $self->can($method) ) { + # Dispatch to the root M:I class + return $self->$method(@_); + } + + # Dispatch to the appropriate plugin + unshift @_, ( $self, $1 ); + goto &{$self->can('call')}; + }; +} + +sub preload { + my $self = shift; + unless ( $self->{extensions} ) { + $self->load_extensions( + "$self->{prefix}/$self->{path}", $self + ); + } + + my @exts = @{$self->{extensions}}; + unless ( @exts ) { + @exts = $self->{admin}->load_all_extensions; + } + + my %seen; + foreach my $obj ( @exts ) { + while (my ($method, $glob) = each %{ref($obj) . '::'}) { + next unless $obj->can($method); + next if $method =~ /^_/; + next if $method eq uc($method); + $seen{$method}++; + } + } + + my $who = $self->_caller; + foreach my $name ( sort keys %seen ) { + local $^W; + *{"${who}::$name"} = sub { + ${"${who}::AUTOLOAD"} = "${who}::$name"; + goto &{"${who}::AUTOLOAD"}; + }; + } +} + +sub new { + my ($class, %args) = @_; + + delete $INC{'FindBin.pm'}; + { + # to suppress the redefine warning + local $SIG{__WARN__} = sub {}; + require FindBin; + } + + # ignore the prefix on extension modules built from top level. + my $base_path = Cwd::abs_path($FindBin::Bin); + unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) { + delete $args{prefix}; + } + return $args{_self} if $args{_self}; + + $args{dispatch} ||= 'Admin'; + $args{prefix} ||= 'inc'; + $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author'); + $args{bundle} ||= 'inc/BUNDLES'; + $args{base} ||= $base_path; + $class =~ s/^\Q$args{prefix}\E:://; + $args{name} ||= $class; + $args{version} ||= $class->VERSION; + unless ( $args{path} ) { + $args{path} = $args{name}; + $args{path} =~ s!::!/!g; + } + $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm"; + $args{wrote} = 0; + + bless( \%args, $class ); +} + +sub call { + my ($self, $method) = @_; + my $obj = $self->load($method) or return; + splice(@_, 0, 2, $obj); + goto &{$obj->can($method)}; +} + +sub load { + my ($self, $method) = @_; + + $self->load_extensions( + "$self->{prefix}/$self->{path}", $self + ) unless $self->{extensions}; + + foreach my $obj (@{$self->{extensions}}) { + return $obj if $obj->can($method); + } + + my $admin = $self->{admin} or die <<"END_DIE"; +The '$method' method does not exist in the '$self->{prefix}' path! +Please remove the '$self->{prefix}' directory and run $0 again to load it. +END_DIE + + my $obj = $admin->load($method, 1); + push @{$self->{extensions}}, $obj; + + $obj; +} + +sub load_extensions { + my ($self, $path, $top) = @_; + + my $should_reload = 0; + unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) { + unshift @INC, $self->{prefix}; + $should_reload = 1; + } + + foreach my $rv ( $self->find_extensions($path) ) { + my ($file, $pkg) = @{$rv}; + next if $self->{pathnames}{$pkg}; + + local $@; + my $new = eval { local $^W; require $file; $pkg->can('new') }; + unless ( $new ) { + warn $@ if $@; + next; + } + $self->{pathnames}{$pkg} = + $should_reload ? delete $INC{$file} : $INC{$file}; + push @{$self->{extensions}}, &{$new}($pkg, _top => $top ); + } + + $self->{extensions} ||= []; +} + +sub find_extensions { + my ($self, $path) = @_; + + my @found; + File::Find::find( sub { + my $file = $File::Find::name; + return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; + my $subpath = $1; + return if lc($subpath) eq lc($self->{dispatch}); + + $file = "$self->{path}/$subpath.pm"; + my $pkg = "$self->{name}::$subpath"; + $pkg =~ s!/!::!g; + + # If we have a mixed-case package name, assume case has been preserved + # correctly. Otherwise, root through the file to locate the case-preserved + # version of the package name. + if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) { + my $content = Module::Install::_read($subpath . '.pm'); + my $in_pod = 0; + foreach ( split //, $content ) { + $in_pod = 1 if /^=\w/; + $in_pod = 0 if /^=cut/; + next if ($in_pod || /^=cut/); # skip pod text + next if /^\s*#/; # and comments + if ( m/^\s*package\s+($pkg)\s*;/i ) { + $pkg = $1; + last; + } + } + } + + push @found, [ $file, $pkg ]; + }, $path ) if -d $path; + + @found; +} + + + + + +##################################################################### +# Common Utility Functions + +sub _caller { + my $depth = 0; + my $call = caller($depth); + while ( $call eq __PACKAGE__ ) { + $depth++; + $call = caller($depth); + } + return $call; +} + +# Done in evals to avoid confusing Perl::MinimumVersion +eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; +sub _read { + local *FH; + open( FH, '<', $_[0] ) or die "open($_[0]): $!"; + my $string = do { local $/; <FH> }; + close FH or die "close($_[0]): $!"; + return $string; +} +END_NEW +sub _read { + local *FH; + open( FH, "< $_[0]" ) or die "open($_[0]): $!"; + my $string = do { local $/; <FH> }; + close FH or die "close($_[0]): $!"; + return $string; +} +END_OLD + +sub _readperl { + my $string = Module::Install::_read($_[0]); + $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; + $string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s; + $string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg; + return $string; +} + +sub _readpod { + my $string = Module::Install::_read($_[0]); + $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; + return $string if $_[0] =~ /\.pod\z/; + $string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg; + $string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg; + $string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg; + $string =~ s/^\n+//s; + return $string; +} + +# Done in evals to avoid confusing Perl::MinimumVersion +eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; +sub _write { + local *FH; + open( FH, '>', $_[0] ) or die "open($_[0]): $!"; + foreach ( 1 .. $#_ ) { + print FH $_[$_] or die "print($_[0]): $!"; + } + close FH or die "close($_[0]): $!"; +} +END_NEW +sub _write { + local *FH; + open( FH, "> $_[0]" ) or die "open($_[0]): $!"; + foreach ( 1 .. $#_ ) { + print FH $_[$_] or die "print($_[0]): $!"; + } + close FH or die "close($_[0]): $!"; +} +END_OLD + +# _version is for processing module versions (eg, 1.03_05) not +# Perl versions (eg, 5.8.1). +sub _version ($) { + my $s = shift || 0; + my $d =()= $s =~ /(\.)/g; + if ( $d >= 2 ) { + # Normalise multipart versions + $s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg; + } + $s =~ s/^(\d+)\.?//; + my $l = $1 || 0; + my @v = map { + $_ . '0' x (3 - length $_) + } $s =~ /(\d{1,3})\D?/g; + $l = $l . '.' . join '', @v if @v; + return $l + 0; +} + +sub _cmp ($$) { + _version($_[0]) <=> _version($_[1]); +} + +# Cloned from Params::Util::_CLASS +sub _CLASS ($) { + ( + defined $_[0] + and + ! ref $_[0] + and + $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s + ) ? $_[0] : undef; +} + +1; + +# Copyright 2008 - 2011 Adam Kennedy. diff --git a/cpan/Math-BigInt-FastCalc/inc/Module/Install/Base.pm b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Base.pm new file mode 100644 index 0000000000..d3662c9e80 --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Base.pm @@ -0,0 +1,83 @@ +#line 1 +package Module::Install::Base; + +use strict 'vars'; +use vars qw{$VERSION}; +BEGIN { + $VERSION = '1.01'; +} + +# Suspend handler for "redefined" warnings +BEGIN { + my $w = $SIG{__WARN__}; + $SIG{__WARN__} = sub { $w }; +} + +#line 42 + +sub new { + my $class = shift; + unless ( defined &{"${class}::call"} ) { + *{"${class}::call"} = sub { shift->_top->call(@_) }; + } + unless ( defined &{"${class}::load"} ) { + *{"${class}::load"} = sub { shift->_top->load(@_) }; + } + bless { @_ }, $class; +} + +#line 61 + +sub AUTOLOAD { + local $@; + my $func = eval { shift->_top->autoload } or return; + goto &$func; +} + +#line 75 + +sub _top { + $_[0]->{_top}; +} + +#line 90 + +sub admin { + $_[0]->_top->{admin} + or + Module::Install::Base::FakeAdmin->new; +} + +#line 106 + +sub is_admin { + ! $_[0]->admin->isa('Module::Install::Base::FakeAdmin'); +} + +sub DESTROY {} + +package Module::Install::Base::FakeAdmin; + +use vars qw{$VERSION}; +BEGIN { + $VERSION = $Module::Install::Base::VERSION; +} + +my $fake; + +sub new { + $fake ||= bless(\@_, $_[0]); +} + +sub AUTOLOAD {} + +sub DESTROY {} + +# Restore warning handler +BEGIN { + $SIG{__WARN__} = $SIG{__WARN__}->(); +} + +1; + +#line 159 diff --git a/cpan/Math-BigInt-FastCalc/inc/Module/Install/Can.pm b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Can.pm new file mode 100644 index 0000000000..276409a9ba --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Can.pm @@ -0,0 +1,81 @@ +#line 1 +package Module::Install::Can; + +use strict; +use Config (); +use File::Spec (); +use ExtUtils::MakeMaker (); +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.01'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +# check if we can load some module +### Upgrade this to not have to load the module if possible +sub can_use { + my ($self, $mod, $ver) = @_; + $mod =~ s{::|\\}{/}g; + $mod .= '.pm' unless $mod =~ /\.pm$/i; + + my $pkg = $mod; + $pkg =~ s{/}{::}g; + $pkg =~ s{\.pm$}{}i; + + local $@; + eval { require $mod; $pkg->VERSION($ver || 0); 1 }; +} + +# check if we can run some command +sub can_run { + my ($self, $cmd) = @_; + + my $_cmd = $cmd; + return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); + + for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { + next if $dir eq ''; + my $abs = File::Spec->catfile($dir, $_[1]); + return $abs if (-x $abs or $abs = MM->maybe_command($abs)); + } + + return; +} + +# can we locate a (the) C compiler +sub can_cc { + my $self = shift; + my @chunks = split(/ /, $Config::Config{cc}) or return; + + # $Config{cc} may contain args; try to find out the program part + while (@chunks) { + return $self->can_run("@chunks") || (pop(@chunks), next); + } + + return; +} + +# Fix Cygwin bug on maybe_command(); +if ( $^O eq 'cygwin' ) { + require ExtUtils::MM_Cygwin; + require ExtUtils::MM_Win32; + if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { + *ExtUtils::MM_Cygwin::maybe_command = sub { + my ($self, $file) = @_; + if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { + ExtUtils::MM_Win32->maybe_command($file); + } else { + ExtUtils::MM_Unix->maybe_command($file); + } + } + } +} + +1; + +__END__ + +#line 156 diff --git a/cpan/Math-BigInt-FastCalc/inc/Module/Install/Fetch.pm b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Fetch.pm new file mode 100644 index 0000000000..093cb7af5c --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Fetch.pm @@ -0,0 +1,93 @@ +#line 1 +package Module::Install::Fetch; + +use strict; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.01'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +sub get_file { + my ($self, %args) = @_; + my ($scheme, $host, $path, $file) = + $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; + + if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) { + $args{url} = $args{ftp_url} + or (warn("LWP support unavailable!\n"), return); + ($scheme, $host, $path, $file) = + $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; + } + + $|++; + print "Fetching '$file' from $host... "; + + unless (eval { require Socket; Socket::inet_aton($host) }) { + warn "'$host' resolve failed!\n"; + return; + } + + return unless $scheme eq 'ftp' or $scheme eq 'http'; + + require Cwd; + my $dir = Cwd::getcwd(); + chdir $args{local_dir} or return if exists $args{local_dir}; + + if (eval { require LWP::Simple; 1 }) { + LWP::Simple::mirror($args{url}, $file); + } + elsif (eval { require Net::FTP; 1 }) { eval { + # use Net::FTP to get past firewall + my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); + $ftp->login("anonymous", 'anonymous@example.com'); + $ftp->cwd($path); + $ftp->binary; + $ftp->get($file) or (warn("$!\n"), return); + $ftp->quit; + } } + elsif (my $ftp = $self->can_run('ftp')) { eval { + # no Net::FTP, fallback to ftp.exe + require FileHandle; + my $fh = FileHandle->new; + + local $SIG{CHLD} = 'IGNORE'; + unless ($fh->open("|$ftp -n")) { + warn "Couldn't open ftp: $!\n"; + chdir $dir; return; + } + + my @dialog = split(/\n/, <<"END_FTP"); +open $host +user anonymous anonymous\@example.com +cd $path +binary +get $file $file +quit +END_FTP + foreach (@dialog) { $fh->print("$_\n") } + $fh->close; + } } + else { + warn "No working 'ftp' program available!\n"; + chdir $dir; return; + } + + unless (-f $file) { + warn "Fetching failed: $@\n"; + chdir $dir; return; + } + + return if exists $args{size} and -s $file != $args{size}; + system($args{run}) if exists $args{run}; + unlink($file) if $args{remove}; + + print(((!exists $args{check_for} or -e $args{check_for}) + ? "done!" : "failed! ($!)"), "\n"); + chdir $dir; return !$?; +} + +1; diff --git a/cpan/Math-BigInt-FastCalc/inc/Module/Install/Makefile.pm b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Makefile.pm new file mode 100644 index 0000000000..4c710039b3 --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Makefile.pm @@ -0,0 +1,415 @@ +#line 1 +package Module::Install::Makefile; + +use strict 'vars'; +use ExtUtils::MakeMaker (); +use Module::Install::Base (); +use Fcntl qw/:flock :seek/; + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.01'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +sub Makefile { $_[0] } + +my %seen = (); + +sub prompt { + shift; + + # Infinite loop protection + my @c = caller(); + if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) { + die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])"; + } + + # In automated testing or non-interactive session, always use defaults + if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) { + local $ENV{PERL_MM_USE_DEFAULT} = 1; + goto &ExtUtils::MakeMaker::prompt; + } else { + goto &ExtUtils::MakeMaker::prompt; + } +} + +# Store a cleaned up version of the MakeMaker version, +# since we need to behave differently in a variety of +# ways based on the MM version. +my $makemaker = eval $ExtUtils::MakeMaker::VERSION; + +# If we are passed a param, do a "newer than" comparison. +# Otherwise, just return the MakeMaker version. +sub makemaker { + ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0 +} + +# Ripped from ExtUtils::MakeMaker 6.56, and slightly modified +# as we only need to know here whether the attribute is an array +# or a hash or something else (which may or may not be appendable). +my %makemaker_argtype = ( + C => 'ARRAY', + CONFIG => 'ARRAY', +# CONFIGURE => 'CODE', # ignore + DIR => 'ARRAY', + DL_FUNCS => 'HASH', + DL_VARS => 'ARRAY', + EXCLUDE_EXT => 'ARRAY', + EXE_FILES => 'ARRAY', + FUNCLIST => 'ARRAY', + H => 'ARRAY', + IMPORTS => 'HASH', + INCLUDE_EXT => 'ARRAY', + LIBS => 'ARRAY', # ignore '' + MAN1PODS => 'HASH', + MAN3PODS => 'HASH', + META_ADD => 'HASH', + META_MERGE => 'HASH', + PL_FILES => 'HASH', + PM => 'HASH', + PMLIBDIRS => 'ARRAY', + PMLIBPARENTDIRS => 'ARRAY', + PREREQ_PM => 'HASH', + CONFIGURE_REQUIRES => 'HASH', + SKIP => 'ARRAY', + TYPEMAPS => 'ARRAY', + XS => 'HASH', +# VERSION => ['version',''], # ignore +# _KEEP_AFTER_FLUSH => '', + + clean => 'HASH', + depend => 'HASH', + dist => 'HASH', + dynamic_lib=> 'HASH', + linkext => 'HASH', + macro => 'HASH', + postamble => 'HASH', + realclean => 'HASH', + test => 'HASH', + tool_autosplit => 'HASH', + + # special cases where you can use makemaker_append + CCFLAGS => 'APPENDABLE', + DEFINE => 'APPENDABLE', + INC => 'APPENDABLE', + LDDLFLAGS => 'APPENDABLE', + LDFROM => 'APPENDABLE', +); + +sub makemaker_args { + my ($self, %new_args) = @_; + my $args = ( $self->{makemaker_args} ||= {} ); + foreach my $key (keys %new_args) { + if ($makemaker_argtype{$key}) { + if ($makemaker_argtype{$key} eq 'ARRAY') { + $args->{$key} = [] unless defined $args->{$key}; + unless (ref $args->{$key} eq 'ARRAY') { + $args->{$key} = [$args->{$key}] + } + push @{$args->{$key}}, + ref $new_args{$key} eq 'ARRAY' + ? @{$new_args{$key}} + : $new_args{$key}; + } + elsif ($makemaker_argtype{$key} eq 'HASH') { + $args->{$key} = {} unless defined $args->{$key}; + foreach my $skey (keys %{ $new_args{$key} }) { + $args->{$key}{$skey} = $new_args{$key}{$skey}; + } + } + elsif ($makemaker_argtype{$key} eq 'APPENDABLE') { + $self->makemaker_append($key => $new_args{$key}); + } + } + else { + if (defined $args->{$key}) { + warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n}; + } + $args->{$key} = $new_args{$key}; + } + } + return $args; +} + +# For mm args that take multiple space-seperated args, +# append an argument to the current list. +sub makemaker_append { + my $self = shift; + my $name = shift; + my $args = $self->makemaker_args; + $args->{$name} = defined $args->{$name} + ? join( ' ', $args->{$name}, @_ ) + : join( ' ', @_ ); +} + +sub build_subdirs { + my $self = shift; + my $subdirs = $self->makemaker_args->{DIR} ||= []; + for my $subdir (@_) { + push @$subdirs, $subdir; + } +} + +sub clean_files { + my $self = shift; + my $clean = $self->makemaker_args->{clean} ||= {}; + %$clean = ( + %$clean, + FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_), + ); +} + +sub realclean_files { + my $self = shift; + my $realclean = $self->makemaker_args->{realclean} ||= {}; + %$realclean = ( + %$realclean, + FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_), + ); +} + +sub libs { + my $self = shift; + my $libs = ref $_[0] ? shift : [ shift ]; + $self->makemaker_args( LIBS => $libs ); +} + +sub inc { + my $self = shift; + $self->makemaker_args( INC => shift ); +} + +sub _wanted_t { +} + +sub tests_recursive { + my $self = shift; + my $dir = shift || 't'; + unless ( -d $dir ) { + die "tests_recursive dir '$dir' does not exist"; + } + my %tests = map { $_ => 1 } split / /, ($self->tests || ''); + require File::Find; + File::Find::find( + sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 }, + $dir + ); + $self->tests( join ' ', sort keys %tests ); +} + +sub write { + my $self = shift; + die "&Makefile->write() takes no arguments\n" if @_; + + # Check the current Perl version + my $perl_version = $self->perl_version; + if ( $perl_version ) { + eval "use $perl_version; 1" + or die "ERROR: perl: Version $] is installed, " + . "but we need version >= $perl_version"; + } + + # Make sure we have a new enough MakeMaker + require ExtUtils::MakeMaker; + + if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) { + # MakeMaker can complain about module versions that include + # an underscore, even though its own version may contain one! + # Hence the funny regexp to get rid of it. See RT #35800 + # for details. + my $v = $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/; + $self->build_requires( 'ExtUtils::MakeMaker' => $v ); + $self->configure_requires( 'ExtUtils::MakeMaker' => $v ); + } else { + # Allow legacy-compatibility with 5.005 by depending on the + # most recent EU:MM that supported 5.005. + $self->build_requires( 'ExtUtils::MakeMaker' => 6.42 ); + $self->configure_requires( 'ExtUtils::MakeMaker' => 6.42 ); + } + + # Generate the MakeMaker params + my $args = $self->makemaker_args; + $args->{DISTNAME} = $self->name; + $args->{NAME} = $self->module_name || $self->name; + $args->{NAME} =~ s/-/::/g; + $args->{VERSION} = $self->version or die <<'EOT'; +ERROR: Can't determine distribution version. Please specify it +explicitly via 'version' in Makefile.PL, or set a valid $VERSION +in a module, and provide its file path via 'version_from' (or +'all_from' if you prefer) in Makefile.PL. +EOT + + $DB::single = 1; + if ( $self->tests ) { + my @tests = split ' ', $self->tests; + my %seen; + $args->{test} = { + TESTS => (join ' ', grep {!$seen{$_}++} @tests), + }; + } elsif ( $Module::Install::ExtraTests::use_extratests ) { + # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness. + # So, just ignore our xt tests here. + } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) { + $args->{test} = { + TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ), + }; + } + if ( $] >= 5.005 ) { + $args->{ABSTRACT} = $self->abstract; + $args->{AUTHOR} = join ', ', @{$self->author || []}; + } + if ( $self->makemaker(6.10) ) { + $args->{NO_META} = 1; + #$args->{NO_MYMETA} = 1; + } + if ( $self->makemaker(6.17) and $self->sign ) { + $args->{SIGN} = 1; + } + unless ( $self->is_admin ) { + delete $args->{SIGN}; + } + if ( $self->makemaker(6.31) and $self->license ) { + $args->{LICENSE} = $self->license; + } + + my $prereq = ($args->{PREREQ_PM} ||= {}); + %$prereq = ( %$prereq, + map { @$_ } # flatten [module => version] + map { @$_ } + grep $_, + ($self->requires) + ); + + # Remove any reference to perl, PREREQ_PM doesn't support it + delete $args->{PREREQ_PM}->{perl}; + + # Merge both kinds of requires into BUILD_REQUIRES + my $build_prereq = ($args->{BUILD_REQUIRES} ||= {}); + %$build_prereq = ( %$build_prereq, + map { @$_ } # flatten [module => version] + map { @$_ } + grep $_, + ($self->configure_requires, $self->build_requires) + ); + + # Remove any reference to perl, BUILD_REQUIRES doesn't support it + delete $args->{BUILD_REQUIRES}->{perl}; + + # Delete bundled dists from prereq_pm, add it to Makefile DIR + my $subdirs = ($args->{DIR} || []); + if ($self->bundles) { + my %processed; + foreach my $bundle (@{ $self->bundles }) { + my ($mod_name, $dist_dir) = @$bundle; + delete $prereq->{$mod_name}; + $dist_dir = File::Basename::basename($dist_dir); # dir for building this module + if (not exists $processed{$dist_dir}) { + if (-d $dist_dir) { + # List as sub-directory to be processed by make + push @$subdirs, $dist_dir; + } + # Else do nothing: the module is already present on the system + $processed{$dist_dir} = undef; + } + } + } + + unless ( $self->makemaker('6.55_03') ) { + %$prereq = (%$prereq,%$build_prereq); + delete $args->{BUILD_REQUIRES}; + } + + if ( my $perl_version = $self->perl_version ) { + eval "use $perl_version; 1" + or die "ERROR: perl: Version $] is installed, " + . "but we need version >= $perl_version"; + + if ( $self->makemaker(6.48) ) { + $args->{MIN_PERL_VERSION} = $perl_version; + } + } + + if ($self->installdirs) { + warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS}; + $args->{INSTALLDIRS} = $self->installdirs; + } + + my %args = map { + ( $_ => $args->{$_} ) } grep {defined($args->{$_} ) + } keys %$args; + + my $user_preop = delete $args{dist}->{PREOP}; + if ( my $preop = $self->admin->preop($user_preop) ) { + foreach my $key ( keys %$preop ) { + $args{dist}->{$key} = $preop->{$key}; + } + } + + my $mm = ExtUtils::MakeMaker::WriteMakefile(%args); + $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile'); +} + +sub fix_up_makefile { + my $self = shift; + my $makefile_name = shift; + my $top_class = ref($self->_top) || ''; + my $top_version = $self->_top->VERSION || ''; + + my $preamble = $self->preamble + ? "# Preamble by $top_class $top_version\n" + . $self->preamble + : ''; + my $postamble = "# Postamble by $top_class $top_version\n" + . ($self->postamble || ''); + + local *MAKEFILE; + open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!"; + eval { flock MAKEFILE, LOCK_EX }; + my $makefile = do { local $/; <MAKEFILE> }; + + $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /; + $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g; + $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g; + $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m; + $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m; + + # Module::Install will never be used to build the Core Perl + # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks + # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist + $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m; + #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m; + + # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well. + $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g; + + # XXX - This is currently unused; not sure if it breaks other MM-users + # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg; + + seek MAKEFILE, 0, SEEK_SET; + truncate MAKEFILE, 0; + print MAKEFILE "$preamble$makefile$postamble" or die $!; + close MAKEFILE or die $!; + + 1; +} + +sub preamble { + my ($self, $text) = @_; + $self->{preamble} = $text . $self->{preamble} if defined $text; + $self->{preamble}; +} + +sub postamble { + my ($self, $text) = @_; + $self->{postamble} ||= $self->admin->postamble; + $self->{postamble} .= $text if defined $text; + $self->{postamble} +} + +1; + +__END__ + +#line 541 diff --git a/cpan/Math-BigInt-FastCalc/inc/Module/Install/Metadata.pm b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Metadata.pm new file mode 100644 index 0000000000..3b01e098dd --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Metadata.pm @@ -0,0 +1,716 @@ +#line 1 +package Module::Install::Metadata; + +use strict 'vars'; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.01'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +my @boolean_keys = qw{ + sign +}; + +my @scalar_keys = qw{ + name + module_name + abstract + version + distribution_type + tests + installdirs +}; + +my @tuple_keys = qw{ + configure_requires + build_requires + requires + recommends + bundles + resources +}; + +my @resource_keys = qw{ + homepage + bugtracker + repository +}; + +my @array_keys = qw{ + keywords + author +}; + +*authors = \&author; + +sub Meta { shift } +sub Meta_BooleanKeys { @boolean_keys } +sub Meta_ScalarKeys { @scalar_keys } +sub Meta_TupleKeys { @tuple_keys } +sub Meta_ResourceKeys { @resource_keys } +sub Meta_ArrayKeys { @array_keys } + +foreach my $key ( @boolean_keys ) { + *$key = sub { + my $self = shift; + if ( defined wantarray and not @_ ) { + return $self->{values}->{$key}; + } + $self->{values}->{$key} = ( @_ ? $_[0] : 1 ); + return $self; + }; +} + +foreach my $key ( @scalar_keys ) { + *$key = sub { + my $self = shift; + return $self->{values}->{$key} if defined wantarray and !@_; + $self->{values}->{$key} = shift; + return $self; + }; +} + +foreach my $key ( @array_keys ) { + *$key = sub { + my $self = shift; + return $self->{values}->{$key} if defined wantarray and !@_; + $self->{values}->{$key} ||= []; + push @{$self->{values}->{$key}}, @_; + return $self; + }; +} + +foreach my $key ( @resource_keys ) { + *$key = sub { + my $self = shift; + unless ( @_ ) { + return () unless $self->{values}->{resources}; + return map { $_->[1] } + grep { $_->[0] eq $key } + @{ $self->{values}->{resources} }; + } + return $self->{values}->{resources}->{$key} unless @_; + my $uri = shift or die( + "Did not provide a value to $key()" + ); + $self->resources( $key => $uri ); + return 1; + }; +} + +foreach my $key ( grep { $_ ne "resources" } @tuple_keys) { + *$key = sub { + my $self = shift; + return $self->{values}->{$key} unless @_; + my @added; + while ( @_ ) { + my $module = shift or last; + my $version = shift || 0; + push @added, [ $module, $version ]; + } + push @{ $self->{values}->{$key} }, @added; + return map {@$_} @added; + }; +} + +# Resource handling +my %lc_resource = map { $_ => 1 } qw{ + homepage + license + bugtracker + repository +}; + +sub resources { + my $self = shift; + while ( @_ ) { + my $name = shift or last; + my $value = shift or next; + if ( $name eq lc $name and ! $lc_resource{$name} ) { + die("Unsupported reserved lowercase resource '$name'"); + } + $self->{values}->{resources} ||= []; + push @{ $self->{values}->{resources} }, [ $name, $value ]; + } + $self->{values}->{resources}; +} + +# Aliases for build_requires that will have alternative +# meanings in some future version of META.yml. +sub test_requires { shift->build_requires(@_) } +sub install_requires { shift->build_requires(@_) } + +# Aliases for installdirs options +sub install_as_core { $_[0]->installdirs('perl') } +sub install_as_cpan { $_[0]->installdirs('site') } +sub install_as_site { $_[0]->installdirs('site') } +sub install_as_vendor { $_[0]->installdirs('vendor') } + +sub dynamic_config { + my $self = shift; + unless ( @_ ) { + warn "You MUST provide an explicit true/false value to dynamic_config\n"; + return $self; + } + $self->{values}->{dynamic_config} = $_[0] ? 1 : 0; + return 1; +} + +sub perl_version { + my $self = shift; + return $self->{values}->{perl_version} unless @_; + my $version = shift or die( + "Did not provide a value to perl_version()" + ); + + # Normalize the version + $version = $self->_perl_version($version); + + # We don't support the reall old versions + unless ( $version >= 5.005 ) { + die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n"; + } + + $self->{values}->{perl_version} = $version; +} + +sub all_from { + my ( $self, $file ) = @_; + + unless ( defined($file) ) { + my $name = $self->name or die( + "all_from called with no args without setting name() first" + ); + $file = join('/', 'lib', split(/-/, $name)) . '.pm'; + $file =~ s{.*/}{} unless -e $file; + unless ( -e $file ) { + die("all_from cannot find $file from $name"); + } + } + unless ( -f $file ) { + die("The path '$file' does not exist, or is not a file"); + } + + $self->{values}{all_from} = $file; + + # Some methods pull from POD instead of code. + # If there is a matching .pod, use that instead + my $pod = $file; + $pod =~ s/\.pm$/.pod/i; + $pod = $file unless -e $pod; + + # Pull the different values + $self->name_from($file) unless $self->name; + $self->version_from($file) unless $self->version; + $self->perl_version_from($file) unless $self->perl_version; + $self->author_from($pod) unless @{$self->author || []}; + $self->license_from($pod) unless $self->license; + $self->abstract_from($pod) unless $self->abstract; + + return 1; +} + +sub provides { + my $self = shift; + my $provides = ( $self->{values}->{provides} ||= {} ); + %$provides = (%$provides, @_) if @_; + return $provides; +} + +sub auto_provides { + my $self = shift; + return $self unless $self->is_admin; + unless (-e 'MANIFEST') { + warn "Cannot deduce auto_provides without a MANIFEST, skipping\n"; + return $self; + } + # Avoid spurious warnings as we are not checking manifest here. + local $SIG{__WARN__} = sub {1}; + require ExtUtils::Manifest; + local *ExtUtils::Manifest::manicheck = sub { return }; + + require Module::Build; + my $build = Module::Build->new( + dist_name => $self->name, + dist_version => $self->version, + license => $self->license, + ); + $self->provides( %{ $build->find_dist_packages || {} } ); +} + +sub feature { + my $self = shift; + my $name = shift; + my $features = ( $self->{values}->{features} ||= [] ); + my $mods; + + if ( @_ == 1 and ref( $_[0] ) ) { + # The user used ->feature like ->features by passing in the second + # argument as a reference. Accomodate for that. + $mods = $_[0]; + } else { + $mods = \@_; + } + + my $count = 0; + push @$features, ( + $name => [ + map { + ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_ + } @$mods + ] + ); + + return @$features; +} + +sub features { + my $self = shift; + while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) { + $self->feature( $name, @$mods ); + } + return $self->{values}->{features} + ? @{ $self->{values}->{features} } + : (); +} + +sub no_index { + my $self = shift; + my $type = shift; + push @{ $self->{values}->{no_index}->{$type} }, @_ if $type; + return $self->{values}->{no_index}; +} + +sub read { + my $self = shift; + $self->include_deps( 'YAML::Tiny', 0 ); + + require YAML::Tiny; + my $data = YAML::Tiny::LoadFile('META.yml'); + + # Call methods explicitly in case user has already set some values. + while ( my ( $key, $value ) = each %$data ) { + next unless $self->can($key); + if ( ref $value eq 'HASH' ) { + while ( my ( $module, $version ) = each %$value ) { + $self->can($key)->($self, $module => $version ); + } + } else { + $self->can($key)->($self, $value); + } + } + return $self; +} + +sub write { + my $self = shift; + return $self unless $self->is_admin; + $self->admin->write_meta; + return $self; +} + +sub version_from { + require ExtUtils::MM_Unix; + my ( $self, $file ) = @_; + $self->version( ExtUtils::MM_Unix->parse_version($file) ); + + # for version integrity check + $self->makemaker_args( VERSION_FROM => $file ); +} + +sub abstract_from { + require ExtUtils::MM_Unix; + my ( $self, $file ) = @_; + $self->abstract( + bless( + { DISTNAME => $self->name }, + 'ExtUtils::MM_Unix' + )->parse_abstract($file) + ); +} + +# Add both distribution and module name +sub name_from { + my ($self, $file) = @_; + if ( + Module::Install::_read($file) =~ m/ + ^ \s* + package \s* + ([\w:]+) + \s* ; + /ixms + ) { + my ($name, $module_name) = ($1, $1); + $name =~ s{::}{-}g; + $self->name($name); + unless ( $self->module_name ) { + $self->module_name($module_name); + } + } else { + die("Cannot determine name from $file\n"); + } +} + +sub _extract_perl_version { + if ( + $_[0] =~ m/ + ^\s* + (?:use|require) \s* + v? + ([\d_\.]+) + \s* ; + /ixms + ) { + my $perl_version = $1; + $perl_version =~ s{_}{}g; + return $perl_version; + } else { + return; + } +} + +sub perl_version_from { + my $self = shift; + my $perl_version=_extract_perl_version(Module::Install::_read($_[0])); + if ($perl_version) { + $self->perl_version($perl_version); + } else { + warn "Cannot determine perl version info from $_[0]\n"; + return; + } +} + +sub author_from { + my $self = shift; + my $content = Module::Install::_read($_[0]); + if ($content =~ m/ + =head \d \s+ (?:authors?)\b \s* + ([^\n]*) + | + =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s* + .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s* + ([^\n]*) + /ixms) { + my $author = $1 || $2; + + # XXX: ugly but should work anyway... + if (eval "require Pod::Escapes; 1") { + # Pod::Escapes has a mapping table. + # It's in core of perl >= 5.9.3, and should be installed + # as one of the Pod::Simple's prereqs, which is a prereq + # of Pod::Text 3.x (see also below). + $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } + { + defined $2 + ? chr($2) + : defined $Pod::Escapes::Name2character_number{$1} + ? chr($Pod::Escapes::Name2character_number{$1}) + : do { + warn "Unknown escape: E<$1>"; + "E<$1>"; + }; + }gex; + } + elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) { + # Pod::Text < 3.0 has yet another mapping table, + # though the table name of 2.x and 1.x are different. + # (1.x is in core of Perl < 5.6, 2.x is in core of + # Perl < 5.9.3) + my $mapping = ($Pod::Text::VERSION < 2) + ? \%Pod::Text::HTML_Escapes + : \%Pod::Text::ESCAPES; + $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } + { + defined $2 + ? chr($2) + : defined $mapping->{$1} + ? $mapping->{$1} + : do { + warn "Unknown escape: E<$1>"; + "E<$1>"; + }; + }gex; + } + else { + $author =~ s{E<lt>}{<}g; + $author =~ s{E<gt>}{>}g; + } + $self->author($author); + } else { + warn "Cannot determine author info from $_[0]\n"; + } +} + +#Stolen from M::B +my %license_urls = ( + perl => 'http://dev.perl.org/licenses/', + apache => 'http://apache.org/licenses/LICENSE-2.0', + apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1', + artistic => 'http://opensource.org/licenses/artistic-license.php', + artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php', + lgpl => 'http://opensource.org/licenses/lgpl-license.php', + lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php', + lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html', + bsd => 'http://opensource.org/licenses/bsd-license.php', + gpl => 'http://opensource.org/licenses/gpl-license.php', + gpl2 => 'http://opensource.org/licenses/gpl-2.0.php', + gpl3 => 'http://opensource.org/licenses/gpl-3.0.html', + mit => 'http://opensource.org/licenses/mit-license.php', + mozilla => 'http://opensource.org/licenses/mozilla1.1.php', + open_source => undef, + unrestricted => undef, + restrictive => undef, + unknown => undef, +); + +sub license { + my $self = shift; + return $self->{values}->{license} unless @_; + my $license = shift or die( + 'Did not provide a value to license()' + ); + $license = __extract_license($license) || lc $license; + $self->{values}->{license} = $license; + + # Automatically fill in license URLs + if ( $license_urls{$license} ) { + $self->resources( license => $license_urls{$license} ); + } + + return 1; +} + +sub _extract_license { + my $pod = shift; + my $matched; + return __extract_license( + ($matched) = $pod =~ m/ + (=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?) + (=head \d.*|=cut.*|)\z + /xms + ) || __extract_license( + ($matched) = $pod =~ m/ + (=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?) + (=head \d.*|=cut.*|)\z + /xms + ); +} + +sub __extract_license { + my $license_text = shift or return; + my @phrases = ( + '(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1, + '(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1, + 'Artistic and GPL' => 'perl', 1, + 'GNU general public license' => 'gpl', 1, + 'GNU public license' => 'gpl', 1, + 'GNU lesser general public license' => 'lgpl', 1, + 'GNU lesser public license' => 'lgpl', 1, + 'GNU library general public license' => 'lgpl', 1, + 'GNU library public license' => 'lgpl', 1, + 'GNU Free Documentation license' => 'unrestricted', 1, + 'GNU Affero General Public License' => 'open_source', 1, + '(?:Free)?BSD license' => 'bsd', 1, + 'Artistic license 2\.0' => 'artistic_2', 1, + 'Artistic license' => 'artistic', 1, + 'Apache (?:Software )?license' => 'apache', 1, + 'GPL' => 'gpl', 1, + 'LGPL' => 'lgpl', 1, + 'BSD' => 'bsd', 1, + 'Artistic' => 'artistic', 1, + 'MIT' => 'mit', 1, + 'Mozilla Public License' => 'mozilla', 1, + 'Q Public License' => 'open_source', 1, + 'OpenSSL License' => 'unrestricted', 1, + 'SSLeay License' => 'unrestricted', 1, + 'zlib License' => 'open_source', 1, + 'proprietary' => 'proprietary', 0, + ); + while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) { + $pattern =~ s#\s+#\\s+#gs; + if ( $license_text =~ /\b$pattern\b/i ) { + return $license; + } + } + return ''; +} + +sub license_from { + my $self = shift; + if (my $license=_extract_license(Module::Install::_read($_[0]))) { + $self->license($license); + } else { + warn "Cannot determine license info from $_[0]\n"; + return 'unknown'; + } +} + +sub _extract_bugtracker { + my @links = $_[0] =~ m#L<( + https?\Q://rt.cpan.org/\E[^>]+| + https?\Q://github.com/\E[\w_]+/[\w_]+/issues| + https?\Q://code.google.com/p/\E[\w_\-]+/issues/list + )>#gx; + my %links; + @links{@links}=(); + @links=keys %links; + return @links; +} + +sub bugtracker_from { + my $self = shift; + my $content = Module::Install::_read($_[0]); + my @links = _extract_bugtracker($content); + unless ( @links ) { + warn "Cannot determine bugtracker info from $_[0]\n"; + return 0; + } + if ( @links > 1 ) { + warn "Found more than one bugtracker link in $_[0]\n"; + return 0; + } + + # Set the bugtracker + bugtracker( $links[0] ); + return 1; +} + +sub requires_from { + my $self = shift; + my $content = Module::Install::_readperl($_[0]); + my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; + while ( @requires ) { + my $module = shift @requires; + my $version = shift @requires; + $self->requires( $module => $version ); + } +} + +sub test_requires_from { + my $self = shift; + my $content = Module::Install::_readperl($_[0]); + my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; + while ( @requires ) { + my $module = shift @requires; + my $version = shift @requires; + $self->test_requires( $module => $version ); + } +} + +# Convert triple-part versions (eg, 5.6.1 or 5.8.9) to +# numbers (eg, 5.006001 or 5.008009). +# Also, convert double-part versions (eg, 5.8) +sub _perl_version { + my $v = $_[-1]; + $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e; + $v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e; + $v =~ s/(\.\d\d\d)000$/$1/; + $v =~ s/_.+$//; + if ( ref($v) ) { + # Numify + $v = $v + 0; + } + return $v; +} + +sub add_metadata { + my $self = shift; + my %hash = @_; + for my $key (keys %hash) { + warn "add_metadata: $key is not prefixed with 'x_'.\n" . + "Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/; + $self->{values}->{$key} = $hash{$key}; + } +} + + +###################################################################### +# MYMETA Support + +sub WriteMyMeta { + die "WriteMyMeta has been deprecated"; +} + +sub write_mymeta_yaml { + my $self = shift; + + # We need YAML::Tiny to write the MYMETA.yml file + unless ( eval { require YAML::Tiny; 1; } ) { + return 1; + } + + # Generate the data + my $meta = $self->_write_mymeta_data or return 1; + + # Save as the MYMETA.yml file + print "Writing MYMETA.yml\n"; + YAML::Tiny::DumpFile('MYMETA.yml', $meta); +} + +sub write_mymeta_json { + my $self = shift; + + # We need JSON to write the MYMETA.json file + unless ( eval { require JSON; 1; } ) { + return 1; + } + + # Generate the data + my $meta = $self->_write_mymeta_data or return 1; + + # Save as the MYMETA.yml file + print "Writing MYMETA.json\n"; + Module::Install::_write( + 'MYMETA.json', + JSON->new->pretty(1)->canonical->encode($meta), + ); +} + +sub _write_mymeta_data { + my $self = shift; + + # If there's no existing META.yml there is nothing we can do + return undef unless -f 'META.yml'; + + # We need Parse::CPAN::Meta to load the file + unless ( eval { require Parse::CPAN::Meta; 1; } ) { + return undef; + } + + # Merge the perl version into the dependencies + my $val = $self->Meta->{values}; + my $perl = delete $val->{perl_version}; + if ( $perl ) { + $val->{requires} ||= []; + my $requires = $val->{requires}; + + # Canonize to three-dot version after Perl 5.6 + if ( $perl >= 5.006 ) { + $perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e + } + unshift @$requires, [ perl => $perl ]; + } + + # Load the advisory META.yml file + my @yaml = Parse::CPAN::Meta::LoadFile('META.yml'); + my $meta = $yaml[0]; + + # Overwrite the non-configure dependency hashs + delete $meta->{requires}; + delete $meta->{build_requires}; + delete $meta->{recommends}; + if ( exists $val->{requires} ) { + $meta->{requires} = { map { @$_ } @{ $val->{requires} } }; + } + if ( exists $val->{build_requires} ) { + $meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } }; + } + + return $meta; +} + +1; diff --git a/cpan/Math-BigInt-FastCalc/inc/Module/Install/Win32.pm b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Win32.pm new file mode 100644 index 0000000000..3139a63e68 --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/inc/Module/Install/Win32.pm @@ -0,0 +1,64 @@ +#line 1 +package Module::Install::Win32; + +use strict; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.01'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +# determine if the user needs nmake, and download it if needed +sub check_nmake { + my $self = shift; + $self->load('can_run'); + $self->load('get_file'); + + require Config; + return unless ( + $^O eq 'MSWin32' and + $Config::Config{make} and + $Config::Config{make} =~ /^nmake\b/i and + ! $self->can_run('nmake') + ); + + print "The required 'nmake' executable not found, fetching it...\n"; + + require File::Basename; + my $rv = $self->get_file( + url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', + ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', + local_dir => File::Basename::dirname($^X), + size => 51928, + run => 'Nmake15.exe /o > nul', + check_for => 'Nmake.exe', + remove => 1, + ); + + die <<'END_MESSAGE' unless $rv; + +------------------------------------------------------------------------------- + +Since you are using Microsoft Windows, you will need the 'nmake' utility +before installation. It's available at: + + http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe + or + ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe + +Please download the file manually, save it to a directory in %PATH% (e.g. +C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to +that directory, and run "Nmake15.exe" from there; that will create the +'nmake.exe' file needed by this module. + +You may then resume the installation process described in README. + +------------------------------------------------------------------------------- +END_MESSAGE + +} + +1; diff --git a/cpan/Math-BigInt-FastCalc/inc/Module/Install/WriteAll.pm b/cpan/Math-BigInt-FastCalc/inc/Module/Install/WriteAll.pm new file mode 100644 index 0000000000..1f724a7bcb --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/inc/Module/Install/WriteAll.pm @@ -0,0 +1,63 @@ +#line 1 +package Module::Install::WriteAll; + +use strict; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.01'; + @ISA = qw{Module::Install::Base}; + $ISCORE = 1; +} + +sub WriteAll { + my $self = shift; + my %args = ( + meta => 1, + sign => 0, + inline => 0, + check_nmake => 1, + @_, + ); + + $self->sign(1) if $args{sign}; + $self->admin->WriteAll(%args) if $self->is_admin; + + $self->check_nmake if $args{check_nmake}; + unless ( $self->makemaker_args->{PL_FILES} ) { + # XXX: This still may be a bit over-defensive... + unless ($self->makemaker(6.25)) { + $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL'; + } + } + + # Until ExtUtils::MakeMaker support MYMETA.yml, make sure + # we clean it up properly ourself. + $self->realclean_files('MYMETA.yml'); + + if ( $args{inline} ) { + $self->Inline->write; + } else { + $self->Makefile->write; + } + + # The Makefile write process adds a couple of dependencies, + # so write the META.yml files after the Makefile. + if ( $args{meta} ) { + $self->Meta->write; + } + + # Experimental support for MYMETA + if ( $ENV{X_MYMETA} ) { + if ( $ENV{X_MYMETA} eq 'JSON' ) { + $self->Meta->write_mymeta_json; + } else { + $self->Meta->write_mymeta_yaml; + } + } + + return 1; +} + +1; diff --git a/cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm b/cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm index 4e903bd4f1..62dab0465d 100644 --- a/cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm +++ b/cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm @@ -1,28 +1,89 @@ package Math::BigInt::FastCalc; -use 5.006; +use 5.006001; use strict; use warnings; +use Carp qw< carp croak >; + use Math::BigInt::Calc 1.999801; -our @ISA = qw< Math::BigInt::Calc >; +BEGIN { + our @ISA = qw< Math::BigInt::Calc >; +} + +our $VERSION = '0.5010'; + +my $MAX_EXP_F; # the maximum possible base 10 exponent with "no integer" +my $MAX_EXP_I; # the maximum possible base 10 exponent with "use integer" +my $BASE_LEN; # the current base exponent in use +my $USE_INT; # whether "use integer" is used in the computations + +sub _base_len { + my $class = shift; + + if (@_) { # if called as setter ... + my ($base_len, $use_int) = @_; + + croak "The base length must be a positive integer" + unless defined($base_len) && $base_len == int($base_len) + && $base_len > 0; + + if ( $use_int && ($base_len > $MAX_EXP_I) || + !$use_int && ($base_len > $MAX_EXP_F)) + { + croak "The maximum base length (exponent) is $MAX_EXP_I with", + " 'use integer' and $MAX_EXP_F without 'use integer'. The", + " requested settings, a base length of $base_len ", + $use_int ? "with" : "without", " 'use integer', is invalid."; + } + + return $class -> SUPER::_base_len($base_len, $use_int); + } + + return $class -> SUPER::_base_len(); +} -our $VERSION = '0.5009'; +BEGIN { + + my @params = Math::BigInt::FastCalc -> SUPER::_base_len(); + $BASE_LEN = $params[0]; + $MAX_EXP_F = $params[8]; + $MAX_EXP_I = $params[9]; + + # With quadmath support it should work with a base length of 17, because the + # maximum intermediate value used in the computations is less than 2**113. + # However, for some reason a base length of 17 doesn't work, but trial and + # error shows that a base length of 15 works for all methods except + # _is_odd() and _is_even(). These two methods determine whether the least + # significand component is odd or even by converting it to a UV and do a + # bitwise & operation. Because of this, we need to limit the base length to + # what fits inside an UV. + + require Config; + my $max_exp_i = int(8 * $Config::Config{uvsize} * log(2) / log(10)); + $MAX_EXP_I = $max_exp_i if $max_exp_i < $MAX_EXP_I; + $MAX_EXP_F = $MAX_EXP_I if $MAX_EXP_I < $MAX_EXP_F; + + ($BASE_LEN, $USE_INT) = $MAX_EXP_I > $MAX_EXP_F ? ($MAX_EXP_I, 1) + : ($MAX_EXP_F, 0); + + Math::BigInt::FastCalc -> SUPER::_base_len($BASE_LEN, $USE_INT); +} ############################################################################## # global constants, flags and accessory -# announce that we are compatible with MBI v1.83 and up -sub api_version () { 2; } +# Announce that we are compatible with MBI v1.83 and up. This method has been +# made redundant. Each backend is now a subclass of Math::BigInt::Lib, which +# provides the methods not present in the subclasses. -# use Calc to override the methods that we do not provide in XS +sub api_version () { 2; } require XSLoader; XSLoader::load(__PACKAGE__, $VERSION, Math::BigInt::Calc->_base_len()); ############################################################################## -############################################################################## 1; @@ -57,12 +118,20 @@ In order to allow for multiple big integer libraries, Math::BigInt was rewritten to use library modules for core math routines. Any module which follows the same API as this can be used instead by using the following: - use Math::BigInt lib => 'libname'; + use Math::BigInt lib => 'libname'; 'libname' is either the long name ('Math::BigInt::Pari'), or only the short version like 'Pari'. To use this library: - use Math::BigInt lib => 'FastCalc'; + use Math::BigInt lib => 'FastCalc'; + +The default behaviour is to chose the best internal representation of big +integers, but the base length used in the internal representation can be +specified explicitly. Note that this must be done before Math::BigInt is loaded. +For example, + + use Math::BigInt::FastCalc base_len => 3; + use Math::BigInt lib => 'FastCalc'; =head1 STORAGE @@ -73,25 +142,25 @@ stored in decimal form chopped into parts. The following functions are now implemented in FastCalc.xs: - _is_odd _is_even _is_one _is_zero - _is_two _is_ten - _zero _one _two _ten - _acmp _len - _inc _dec - __strip_zeros _copy + _is_odd _is_even _is_one _is_zero + _is_two _is_ten + _zero _one _two _ten + _acmp _len + _inc _dec + __strip_zeros _copy =head1 BUGS Please report any bugs or feature requests to C<bug-math-bigint-fastcalc at rt.cpan.org>, or through the web interface at L<https://rt.cpan.org/Ticket/Create.html?Queue=Math-BigInt-FastCalc> -(requires login). -We will be notified, and then you'll automatically be notified of progress on -your bug as I make changes. +(requires login). We will be notified, and then you'll automatically be +notified of progress on your bug as I make changes. =head1 SUPPORT -You can find documentation for this module with the perldoc command. +After installing, you can find documentation for this module with the perldoc +command. perldoc Math::BigInt::FastCalc @@ -99,43 +168,25 @@ You can also look for information at: =over 4 -=item * RT: CPAN's request tracker +=item GitHub -L<https://rt.cpan.org/Public/Dist/Display.html?Name=Math-BigInt-FastCalc> +L<https://github.com/pjacklam/p5-Math-BigInt-FastCalc> -=item * AnnoCPAN: Annotated CPAN documentation +=item RT: CPAN's request tracker -L<http://annocpan.org/dist/Math-BigInt-FastCalc> +L<https://rt.cpan.org/Dist/Display.html?Name=Math-BigInt-FastCalc> -=item * CPAN Ratings +=item MetaCPAN -L<http://cpanratings.perl.org/dist/Math-BigInt-FastCalc> +L<https://metacpan.org/release/Math-BigInt-FastCalc> -=item * Search CPAN - -L<http://search.cpan.org/dist/Math-BigInt-FastCalc/> - -=item * CPAN Testers Matrix +=item CPAN Testers Matrix L<http://matrix.cpantesters.org/?dist=Math-BigInt-FastCalc> -=item * The Bignum mailing list - -=over 4 - -=item * Post to mailing list - -C<bignum at lists.scsys.co.uk> - -=item * View mailing list - -L<http://lists.scsys.co.uk/pipermail/bignum/> +=item CPAN Ratings -=item * Subscribe/Unsubscribe - -L<http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/bignum> - -=back +L<https://cpanratings.perl.org/dist/Math-BigInt-FastCalc> =back @@ -148,12 +199,13 @@ the same terms as Perl itself. Original math code by Mark Biggar, rewritten by Tels L<http://bloodgate.com/> in late 2000. + Separated from BigInt and shaped API with the help of John Peacock. Fixed, sped-up and enhanced by Tels http://bloodgate.com 2001-2003. Further streamlining (api_version 1 etc.) by Tels 2004-2007. -Bug-fixing by Peter John Acklam E<lt>pjacklam@online.noE<gt> 2010-2016. +Maintained by Peter John Acklam E<lt>pjacklam@gmail.comE<gt> 2010-2021. =head1 SEE ALSO diff --git a/cpan/Math-BigInt-FastCalc/t/bigintfc.t b/cpan/Math-BigInt-FastCalc/t/bigintfc.t index a3dd4a8d37..f8a39fc7ba 100644 --- a/cpan/Math-BigInt-FastCalc/t/bigintfc.t +++ b/cpan/Math-BigInt-FastCalc/t/bigintfc.t @@ -1,425 +1,778 @@ -#!/usr/bin/perl -w +#!perl + +# Test Math::BigInt::FastCalc use strict; -use Test::More tests => 359; +use warnings; + +use Test::More tests => 524; use Math::BigInt::FastCalc; -my ($BASE_LEN, undef, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN_SMALL, $MAX_VAL) = - Math::BigInt::FastCalc->_base_len(); +my ($BASE_LEN, $BASE, $AND_BITS, $XOR_BITS, $OR_BITS, + $BASE_LEN_SMALL, $MAX_VAL, + $MAX_BITS, $MAX_EXP_F, $MAX_EXP_I, $USE_INT) + = Math::BigInt::Calc -> _base_len(); -print "# BASE_LEN = $BASE_LEN\n"; -print "# MAX_VAL = $MAX_VAL\n"; -print "# AND_BITS = $AND_BITS\n"; -print "# XOR_BITS = $XOR_BITS\n"; -print "# IOR_BITS = $OR_BITS\n"; +diag(<<"EOF"); -# testing of Math::BigInt::FastCalc +BASE_LEN = $BASE_LEN +BASE = $BASE +MAX_VAL = $MAX_VAL +AND_BITS = $AND_BITS +XOR_BITS = $XOR_BITS +OR_BITS = $OR_BITS +MAX_EXP_F = $MAX_EXP_F +MAX_EXP_I = $MAX_EXP_I +USE_INT = $USE_INT +EOF -my $C = 'Math::BigInt::FastCalc'; # pass classname to sub's +my $LIB = 'Math::BigInt::FastCalc'; +my $REF = 'ARRAY'; # _new and _str -my $x = $C->_new("123"); my $y = $C->_new("321"); -is (ref($x),'ARRAY'); is ($C->_str($x),123); is ($C->_str($y),321); + +my $x = $LIB->_new("123"); +my $y = $LIB->_new("321"); +is(ref($x), $REF, q|ref($x) is a $REF|); +is($LIB->_str($x), 123, qq|$LIB->_str(\$x) = 123|); +is($LIB->_str($y), 321, qq|$LIB->_str(\$y) = 321|); ############################################################################### # _add, _sub, _mul, _div -is ($C->_str($C->_add($x,$y)),444); -is ($C->_str($C->_sub($x,$y)),123); -is ($C->_str($C->_mul($x,$y)),39483); -is ($C->_str($C->_div($x,$y)),123); + +is($LIB->_str($LIB->_add($x, $y)), 444, + qq|$LIB->_str($LIB->_add(\$x, \$y)) = 444|); +is($LIB->_str($LIB->_sub($x, $y)), 123, + qq|$LIB->_str($LIB->_sub(\$x, \$y)) = 123|); +is($LIB->_str($LIB->_mul($x, $y)), 39483, + qq|$LIB->_str($LIB->_mul(\$x, \$y)) = 39483|); +is($LIB->_str($LIB->_div($x, $y)), 123, + qq|$LIB->_str($LIB->_div(\$x, \$y)) = 123|); ############################################################################### # check that mul/div doesn't change $y # and returns the same reference, not something new -is ($C->_str($C->_mul($x,$y)),39483); -is ($C->_str($x),39483); is ($C->_str($y),321); - -is ($C->_str($C->_div($x,$y)),123); -is ($C->_str($x),123); is ($C->_str($y),321); -$x = $C->_new("39483"); -my ($x1,$r1) = $C->_div($x,$y); -is ("$x1","$x"); -$C->_inc($x1); -is ("$x1","$x"); -is ($C->_str($r1),'0'); - -$x = $C->_new("39483"); # reset +is($LIB->_str($LIB->_mul($x, $y)), 39483, + qq|$LIB->_str($LIB->_mul(\$x, \$y)) = 39483|); +is($LIB->_str($x), 39483, + qq|$LIB->_str(\$x) = 39483|); +is($LIB->_str($y), 321, + qq|$LIB->_str(\$y) = 321|); + +is($LIB->_str($LIB->_div($x, $y)), 123, + qq|$LIB->_str($LIB->_div(\$x, \$y)) = 123|); +is($LIB->_str($x), 123, + qq|$LIB->_str(\$x) = 123|); +is($LIB->_str($y), 321, + qq|$LIB->_str(\$y) = 321|); + +$x = $LIB->_new("39483"); +my ($x1, $r1) = $LIB->_div($x, $y); +is("$x1", "$x", q|"$x1" = "$x"|); +$LIB->_inc($x1); +is("$x1", "$x", q|"$x1" = "$x"|); +is($LIB->_str($r1), "0", qq|$LIB->_str(\$r1) = "0"|); + +$x = $LIB->_new("39483"); # reset ############################################################################### -my $z = $C->_new("2"); -is ($C->_str($C->_add($x,$z)),39485); -my ($re,$rr) = $C->_div($x,$y); -is ($C->_str($re),123); is ($C->_str($rr),2); +my $z = $LIB->_new("2"); +is($LIB->_str($LIB->_add($x, $z)), 39485, + qq|$LIB->_str($LIB->_add(\$x, \$z)) = 39485|); +my ($re, $rr) = $LIB->_div($x, $y); + +is($LIB->_str($re), 123, qq|$LIB->_str(\$re) = 123|); +is($LIB->_str($rr), 2, qq|$LIB->_str(\$rr) = 2|); # is_zero, _is_one, _one, _zero -is ($C->_is_zero($x),''); -is ($C->_is_one($x),''); -is ($C->_str($C->_zero()),"0"); -is ($C->_str($C->_one()),"1"); +ok(! $LIB->_is_zero($x), qq|$LIB->_is_zero(\$x)|); +ok(! $LIB->_is_one($x), qq|$LIB->_is_one(\$x)|); + +is($LIB->_str($LIB->_zero()), "0", qq|$LIB->_str($LIB->_zero()) = "0"|); +is($LIB->_str($LIB->_one()), "1", qq|$LIB->_str($LIB->_one()) = "1"|); # _two() and _ten() -is ($C->_str($C->_two()),"2"); -is ($C->_str($C->_ten()),"10"); -is ($C->_is_ten($C->_two()),''); -is ($C->_is_two($C->_two()),1); -is ($C->_is_ten($C->_ten()),1); -is ($C->_is_two($C->_ten()),''); -is ($C->_is_one($C->_one()),1); -is ($C->_is_one($C->_two()), ''); -is ($C->_is_one($C->_ten()), ''); +is($LIB->_str($LIB->_two()), "2", qq|$LIB->_str($LIB->_two()) = "2"|); +is($LIB->_str($LIB->_ten()), "10", qq|$LIB->_str($LIB->_ten()) = "10"|); -is ($C->_is_one($C->_zero()), ''); +ok(! $LIB->_is_ten($LIB->_two()), qq|$LIB->_is_ten($LIB->_two()) is false|); +ok( $LIB->_is_two($LIB->_two()), qq|$LIB->_is_two($LIB->_two()) is true|); +ok( $LIB->_is_ten($LIB->_ten()), qq|$LIB->_is_ten($LIB->_ten()) is true|); +ok(! $LIB->_is_two($LIB->_ten()), qq|$LIB->_is_two($LIB->_ten()) is false|); -is ($C->_is_zero($C->_zero()),1); +ok( $LIB->_is_one($LIB->_one()), qq|$LIB->_is_one($LIB->_one()) is true|); +ok(! $LIB->_is_one($LIB->_two()), qq|$LIB->_is_one($LIB->_two()) is false|); +ok(! $LIB->_is_one($LIB->_ten()), qq|$LIB->_is_one($LIB->_ten()) is false|); -is ($C->_is_zero($C->_one()), ''); +ok(! $LIB->_is_one($LIB->_zero()), qq/$LIB->_is_one($LIB->_zero()) is false/); +ok( $LIB->_is_zero($LIB->_zero()), qq|$LIB->_is_zero($LIB->_zero()) is true|); +ok(! $LIB->_is_zero($LIB->_one()), qq/$LIB->_is_zero($LIB->_one()) is false/); # is_odd, is_even -is ($C->_is_odd($C->_one()),1); is ($C->_is_odd($C->_zero()),''); -is ($C->_is_even($C->_one()), ''); is ($C->_is_even($C->_zero()),1); - -# _len -for my $method (qw/_alen _len/) - { - $x = $C->_new("1"); is ($C->$method($x),1); - $x = $C->_new("12"); is ($C->$method($x),2); - $x = $C->_new("123"); is ($C->$method($x),3); - $x = $C->_new("1234"); is ($C->$method($x),4); - $x = $C->_new("12345"); is ($C->$method($x),5); - $x = $C->_new("123456"); is ($C->$method($x),6); - $x = $C->_new("1234567"); is ($C->$method($x),7); - $x = $C->_new("12345678"); is ($C->$method($x),8); - $x = $C->_new("123456789"); is ($C->$method($x),9); - - $x = $C->_new("8"); is ($C->$method($x),1); - $x = $C->_new("21"); is ($C->$method($x),2); - $x = $C->_new("321"); is ($C->$method($x),3); - $x = $C->_new("4321"); is ($C->$method($x),4); - $x = $C->_new("54321"); is ($C->$method($x),5); - $x = $C->_new("654321"); is ($C->$method($x),6); - $x = $C->_new("7654321"); is ($C->$method($x),7); - $x = $C->_new("87654321"); is ($C->$method($x),8); - $x = $C->_new("987654321"); is ($C->$method($x),9); - - $x = $C->_new("0"); is ($C->$method($x),1); - $x = $C->_new("20"); is ($C->$method($x),2); - $x = $C->_new("320"); is ($C->$method($x),3); - $x = $C->_new("4320"); is ($C->$method($x),4); - $x = $C->_new("54320"); is ($C->$method($x),5); - $x = $C->_new("654320"); is ($C->$method($x),6); - $x = $C->_new("7654320"); is ($C->$method($x),7); - $x = $C->_new("87654320"); is ($C->$method($x),8); - $x = $C->_new("987654320"); is ($C->$method($x),9); - - for (my $i = 1; $i < 9; $i++) - { - my $a = "$i" . '0' x ($i-1); - $x = $C->_new($a); - print "# Tried len '$a'\n" unless is ($C->_len($x),$i); + +ok( $LIB->_is_odd($LIB->_one()), qq/$LIB->_is_odd($LIB->_one()) is true/); +ok(! $LIB->_is_odd($LIB->_zero()), qq/$LIB->_is_odd($LIB->_zero()) is false/); +ok(! $LIB->_is_even($LIB->_one()), qq/$LIB->_is_even($LIB->_one()) is false/); +ok( $LIB->_is_even($LIB->_zero()), qq/$LIB->_is_even($LIB->_zero()) is true/); + +# _alen and _len + +for my $method (qw/_alen _len/) { + $x = $LIB->_new("1"); + is($LIB->$method($x), 1, qq|$LIB->$method(\$x) = 1|); + $x = $LIB->_new("12"); + is($LIB->$method($x), 2, qq|$LIB->$method(\$x) = 2|); + $x = $LIB->_new("123"); + is($LIB->$method($x), 3, qq|$LIB->$method(\$x) = 3|); + $x = $LIB->_new("1234"); + is($LIB->$method($x), 4, qq|$LIB->$method(\$x) = 4|); + $x = $LIB->_new("12345"); + is($LIB->$method($x), 5, qq|$LIB->$method(\$x) = 5|); + $x = $LIB->_new("123456"); + is($LIB->$method($x), 6, qq|$LIB->$method(\$x) = 6|); + $x = $LIB->_new("1234567"); + is($LIB->$method($x), 7, qq|$LIB->$method(\$x) = 7|); + $x = $LIB->_new("12345678"); + is($LIB->$method($x), 8, qq|$LIB->$method(\$x) = 8|); + $x = $LIB->_new("123456789"); + is($LIB->$method($x), 9, qq|$LIB->$method(\$x) = 9|); + + $x = $LIB->_new("8"); + is($LIB->$method($x), 1, qq|$LIB->$method(\$x) = 1|); + $x = $LIB->_new("21"); + is($LIB->$method($x), 2, qq|$LIB->$method(\$x) = 2|); + $x = $LIB->_new("321"); + is($LIB->$method($x), 3, qq|$LIB->$method(\$x) = 3|); + $x = $LIB->_new("4321"); + is($LIB->$method($x), 4, qq|$LIB->$method(\$x) = 4|); + $x = $LIB->_new("54321"); + is($LIB->$method($x), 5, qq|$LIB->$method(\$x) = 5|); + $x = $LIB->_new("654321"); + is($LIB->$method($x), 6, qq|$LIB->$method(\$x) = 6|); + $x = $LIB->_new("7654321"); + is($LIB->$method($x), 7, qq|$LIB->$method(\$x) = 7|); + $x = $LIB->_new("87654321"); + is($LIB->$method($x), 8, qq|$LIB->$method(\$x) = 8|); + $x = $LIB->_new("987654321"); + is($LIB->$method($x), 9, qq|$LIB->$method(\$x) = 9|); + + $x = $LIB->_new("0"); + is($LIB->$method($x), 1, qq|$LIB->$method(\$x) = 1|); + $x = $LIB->_new("20"); + is($LIB->$method($x), 2, qq|$LIB->$method(\$x) = 2|); + $x = $LIB->_new("320"); + is($LIB->$method($x), 3, qq|$LIB->$method(\$x) = 3|); + $x = $LIB->_new("4320"); + is($LIB->$method($x), 4, qq|$LIB->$method(\$x) = 4|); + $x = $LIB->_new("54320"); + is($LIB->$method($x), 5, qq|$LIB->$method(\$x) = 5|); + $x = $LIB->_new("654320"); + is($LIB->$method($x), 6, qq|$LIB->$method(\$x) = 6|); + $x = $LIB->_new("7654320"); + is($LIB->$method($x), 7, qq|$LIB->$method(\$x) = 7|); + $x = $LIB->_new("87654320"); + is($LIB->$method($x), 8, qq|$LIB->$method(\$x) = 8|); + $x = $LIB->_new("987654320"); + is($LIB->$method($x), 9, qq|$LIB->$method(\$x) = 9|); + + for (my $i = 1; $i < 9; $i++) { + my $a = "$i" . '0' x ($i - 1); + $x = $LIB->_new($a); + is($LIB->_len($x), $i, qq|$LIB->_len(\$x) = $i|); } - } +} # _digit -$x = $C->_new("123456789"); -is ($C->_digit($x,0),9); -is ($C->_digit($x,1),8); -is ($C->_digit($x,2),7); -is ($C->_digit($x,-1),1); -is ($C->_digit($x,-2),2); -is ($C->_digit($x,-3),3); + +$x = $LIB->_new("123456789"); +is($LIB->_digit($x, 0), 9, qq|$LIB->_digit(\$x, 0) = 9|); +is($LIB->_digit($x, 1), 8, qq|$LIB->_digit(\$x, 1) = 8|); +is($LIB->_digit($x, 2), 7, qq|$LIB->_digit(\$x, 2) = 7|); +is($LIB->_digit($x, 8), 1, qq|$LIB->_digit(\$x, 8) = 1|); +is($LIB->_digit($x, 9), 0, qq|$LIB->_digit(\$x, 9) = 0|); +is($LIB->_digit($x, -1), 1, qq|$LIB->_digit(\$x, -1) = 1|); +is($LIB->_digit($x, -2), 2, qq|$LIB->_digit(\$x, -2) = 2|); +is($LIB->_digit($x, -3), 3, qq|$LIB->_digit(\$x, -3) = 3|); +is($LIB->_digit($x, -9), 9, qq|$LIB->_digit(\$x, -9) = 9|); +is($LIB->_digit($x, -10), 0, qq|$LIB->_digit(\$x, -10) = 0|); # _copy -foreach (qw/ 1 12 123 1234 12345 123456 1234567 12345678 123456789/) - { - $x = $C->_new("$_"); - is ($C->_str($C->_copy($x)),"$_"); - is ($C->_str($x),"$_"); # did _copy destroy original x? - } + +foreach (qw/ 1 12 123 1234 12345 123456 1234567 12345678 123456789/) { + $x = $LIB->_new("$_"); + is($LIB->_str($LIB->_copy($x)), "$_", + qq|$LIB->_str($LIB->_copy(\$x)) = "$_"|); + is($LIB->_str($x), "$_", # did _copy destroy original x? + qq|$LIB->_str(\$x) = "$_"|); +} # _zeros -$x = $C->_new("1256000000"); is ($C->_zeros($x),6); -$x = $C->_new("152"); is ($C->_zeros($x),0); -$x = $C->_new("123000"); is ($C->_zeros($x),3); -$x = $C->_new("0"); is ($C->_zeros($x),0); -# _lsft, _rsft -$x = $C->_new("10"); $y = $C->_new("3"); -is ($C->_str($C->_lsft($x,$y,10)),10000); -$x = $C->_new("20"); $y = $C->_new("3"); -is ($C->_str($C->_lsft($x,$y,10)),20000); +$x = $LIB->_new("1256000000"); +is($LIB->_zeros($x), 6, qq|$LIB->_zeros(\$x) = 6|); -$x = $C->_new("128"); $y = $C->_new("4"); -is ($C->_str($C->_lsft($x,$y,2)), 128 << 4); +$x = $LIB->_new("152"); +is($LIB->_zeros($x), 0, qq|$LIB->_zeros(\$x) = 0|); -$x = $C->_new("1000"); $y = $C->_new("3"); -is ($C->_str($C->_rsft($x,$y,10)),1); -$x = $C->_new("20000"); $y = $C->_new("3"); -is ($C->_str($C->_rsft($x,$y,10)),20); -$x = $C->_new("256"); $y = $C->_new("4"); -is ($C->_str($C->_rsft($x,$y,2)),256 >> 4); +$x = $LIB->_new("123000"); +is($LIB->_zeros($x), 3, qq|$LIB->_zeros(\$x) = 3|); -$x = $C->_new("6411906467305339182857313397200584952398"); -$y = $C->_new("45"); -is ($C->_str($C->_rsft($x,$y,10)),0); +$x = $LIB->_new("0"); +is($LIB->_zeros($x), 0, qq|$LIB->_zeros(\$x) = 0|); + +# _lsft, _rsft + +$x = $LIB->_new("10"); +$y = $LIB->_new("3"); +is($LIB->_str($LIB->_lsft($x, $y, 10)), 10000, + qq|$LIB->_str($LIB->_lsft(\$x, \$y, 10)) = 10000|); + +$x = $LIB->_new("20"); +$y = $LIB->_new("3"); +is($LIB->_str($LIB->_lsft($x, $y, 10)), 20000, + qq|$LIB->_str($LIB->_lsft(\$x, \$y, 10)) = 20000|); + +$x = $LIB->_new("128"); +$y = $LIB->_new("4"); +is($LIB->_str($LIB->_lsft($x, $y, 2)), 128 << 4, + qq|$LIB->_str($LIB->_lsft(\$x, \$y, 2)) = 128 << 4|); + +$x = $LIB->_new("1000"); +$y = $LIB->_new("3"); +is($LIB->_str($LIB->_rsft($x, $y, 10)), 1, + qq|$LIB->_str($LIB->_rsft(\$x, \$y, 10)) = 1|); + +$x = $LIB->_new("20000"); +$y = $LIB->_new("3"); +is($LIB->_str($LIB->_rsft($x, $y, 10)), 20, + qq|$LIB->_str($LIB->_rsft(\$x, \$y, 10)) = 20|); + +$x = $LIB->_new("256"); +$y = $LIB->_new("4"); +is($LIB->_str($LIB->_rsft($x, $y, 2)), 256 >> 4, + qq|$LIB->_str($LIB->_rsft(\$x, \$y, 2)) = 256 >> 4|); + +$x = $LIB->_new("6411906467305339182857313397200584952398"); +$y = $LIB->_new("45"); +is($LIB->_str($LIB->_rsft($x, $y, 10)), 0, + qq|$LIB->_str($LIB->_rsft(\$x, \$y, 10)) = 0|); + +# _lsft() with large bases + +for my $xstr ("1", "2", "3") { + for my $nstr ("1", "2", "3") { + for my $bpow (25, 50, 75) { + my $bstr = "1" . ("0" x $bpow); + my $expected = $xstr . ("0" x ($bpow * $nstr)); + my $xobj = $LIB->_new($xstr); + my $nobj = $LIB->_new($nstr); + my $bobj = $LIB->_new($bstr); + + is($LIB->_str($LIB->_lsft($xobj, $nobj, $bobj)), $expected, + qq|$LIB->_str($LIB->_lsft($LIB->_new("$xstr"), | + . qq|$LIB->_new("$nstr"), | + . qq|$LIB->_new("$bstr")))|); + is($LIB->_str($nobj), $nstr, q|$n is unmodified|); + is($LIB->_str($bobj), $bstr, q|$b is unmodified|); + } + } +} # _acmp -$x = $C->_new("123456789"); -$y = $C->_new("987654321"); -is ($C->_acmp($x,$y),-1); -is ($C->_acmp($y,$x),1); -is ($C->_acmp($x,$x),0); -is ($C->_acmp($y,$y),0); -$x = $C->_new("12"); -$y = $C->_new("12"); -is ($C->_acmp($x,$y),0); -$x = $C->_new("21"); -is ($C->_acmp($x,$y),1); -is ($C->_acmp($y,$x),-1); -$x = $C->_new("123456789"); -$y = $C->_new("1987654321"); -is ($C->_acmp($x,$y),-1); -is ($C->_acmp($y,$x),+1); - -$x = $C->_new("1234567890123456789"); -$y = $C->_new("987654321012345678"); -is ($C->_acmp($x,$y),1); -is ($C->_acmp($y,$x),-1); -is ($C->_acmp($x,$x),0); -is ($C->_acmp($y,$y),0); - -$x = $C->_new("1234"); -$y = $C->_new("987654321012345678"); -is ($C->_acmp($x,$y),-1); -is ($C->_acmp($y,$x),1); -is ($C->_acmp($x,$x),0); -is ($C->_acmp($y,$y),0); + +$x = $LIB->_new("123456789"); +$y = $LIB->_new("987654321"); +is($LIB->_acmp($x, $y), -1, qq|$LIB->_acmp(\$x, \$y) = -1|); +is($LIB->_acmp($y, $x), 1, qq|$LIB->_acmp(\$y, \$x) = 1|); +is($LIB->_acmp($x, $x), 0, qq|$LIB->_acmp(\$x, \$x) = 0|); +is($LIB->_acmp($y, $y), 0, qq|$LIB->_acmp(\$y, \$y) = 0|); +$x = $LIB->_new("12"); +$y = $LIB->_new("12"); +is($LIB->_acmp($x, $y), 0, qq|$LIB->_acmp(\$x, \$y) = 0|); +$x = $LIB->_new("21"); +is($LIB->_acmp($x, $y), 1, qq|$LIB->_acmp(\$x, \$y) = 1|); +is($LIB->_acmp($y, $x), -1, qq|$LIB->_acmp(\$y, \$x) = -1|); +$x = $LIB->_new("123456789"); +$y = $LIB->_new("1987654321"); +is($LIB->_acmp($x, $y), -1, qq|$LIB->_acmp(\$x, \$y) = -1|); +is($LIB->_acmp($y, $x), +1, qq|$LIB->_acmp(\$y, \$x) = +1|); + +$x = $LIB->_new("1234567890123456789"); +$y = $LIB->_new("987654321012345678"); +is($LIB->_acmp($x, $y), 1, qq|$LIB->_acmp(\$x, \$y) = 1|); +is($LIB->_acmp($y, $x), -1, qq|$LIB->_acmp(\$y, \$x) = -1|); +is($LIB->_acmp($x, $x), 0, qq|$LIB->_acmp(\$x, \$x) = 0|); +is($LIB->_acmp($y, $y), 0, qq|$LIB->_acmp(\$y, \$y) = 0|); + +$x = $LIB->_new("1234"); +$y = $LIB->_new("987654321012345678"); +is($LIB->_acmp($x, $y), -1, qq|$LIB->_acmp(\$x, \$y) = -1|); +is($LIB->_acmp($y, $x), 1, qq|$LIB->_acmp(\$y, \$x) = 1|); +is($LIB->_acmp($x, $x), 0, qq|$LIB->_acmp(\$x, \$x) = 0|); +is($LIB->_acmp($y, $y), 0, qq|$LIB->_acmp(\$y, \$y) = 0|); # _modinv -$x = $C->_new("8"); -$y = $C->_new("5033"); -my ($xmod,$sign) = $C->_modinv($x,$y); -is ($C->_str($xmod),'629'); # -629 % 5033 == 4404 -is ($sign, '-'); + +$x = $LIB->_new("8"); +$y = $LIB->_new("5033"); +my ($xmod, $sign) = $LIB->_modinv($x, $y); +is($LIB->_str($xmod), "629", # -629 % 5033 == 4404 + qq|$LIB->_str(\$xmod) = "629"|); +is($sign, "-", q|$sign = "-"|); # _div -$x = $C->_new("3333"); $y = $C->_new("1111"); -is ($C->_str(scalar $C->_div($x,$y)),3); -$x = $C->_new("33333"); $y = $C->_new("1111"); ($x,$y) = $C->_div($x,$y); -is ($C->_str($x),30); is ($C->_str($y),3); -$x = $C->_new("123"); $y = $C->_new("1111"); -($x,$y) = $C->_div($x,$y); is ($C->_str($x),0); is ($C->_str($y),123); -# _num -foreach (qw/1 12 123 1234 12345 1234567 12345678 123456789 1234567890/) - { - $x = $C->_new("$_"); - is (ref($x),'ARRAY'); is ($C->_str($x),"$_"); - $x = $C->_num($x); is (ref($x),''); is ($x,$_); - } +$x = $LIB->_new("3333"); +$y = $LIB->_new("1111"); +is($LIB->_str(scalar($LIB->_div($x, $y))), 3, + qq|$LIB->_str(scalar($LIB->_div(\$x, \$y))) = 3|); -# _sqrt -$x = $C->_new("144"); is ($C->_str($C->_sqrt($x)),'12'); -$x = $C->_new("144000000000000"); is ($C->_str($C->_sqrt($x)),'12000000'); +$x = $LIB->_new("33333"); +$y = $LIB->_new("1111"); +($x, $y) = $LIB->_div($x, $y); +is($LIB->_str($x), 30, qq|$LIB->_str(\$x) = 30|); +is($LIB->_str($y), 3, qq|$LIB->_str(\$y) = 3|); -# _root -$x = $C->_new("81"); my $n = $C->_new("3"); # 4*4*4 = 64, 5*5*5 = 125 -is ($C->_str($C->_root($x,$n)),'4'); # 4.xx => 4.0 -$x = $C->_new("81"); $n = $C->_new("4"); # 3*3*3*3 == 81 -is ($C->_str($C->_root($x,$n)),'3'); +$x = $LIB->_new("123"); +$y = $LIB->_new("1111"); +($x, $y) = $LIB->_div($x, $y); +is($LIB->_str($x), 0, qq|$LIB->_str(\$x) = 0|); +is($LIB->_str($y), 123, qq|$LIB->_str(\$y) = 123|); -# _pow (and _root) -$x = $C->_new("0"); $n = $C->_new("3"); # 0 ** y => 0 -is ($C->_str($C->_pow($x,$n)), 0); -$x = $C->_new("3"); $n = $C->_new("0"); # x ** 0 => 1 -is ($C->_str($C->_pow($x,$n)), 1); -$x = $C->_new("1"); $n = $C->_new("3"); # 1 ** y => 1 -is ($C->_str($C->_pow($x,$n)), 1); -$x = $C->_new("5"); $n = $C->_new("1"); # x ** 1 => x -is ($C->_str($C->_pow($x,$n)), 5); +# _num + +foreach (qw/1 12 123 1234 12345 1234567 12345678 123456789 1234567890/) { -$x = $C->_new("81"); $n = $C->_new("3"); # 81 ** 3 == 531441 -is ($C->_str($C->_pow($x,$n)),81 ** 3); + $x = $LIB->_new("$_"); + is(ref($x), $REF, q|ref($x) = "$REF"|); + is($LIB->_str($x), "$_", qq|$LIB->_str(\$x) = "$_"|); -is ($C->_str($C->_root($x,$n)),81); + $x = $LIB->_num($x); + is(ref($x), "", q|ref($x) = ""|); + is($x, $_, qq|\$x = $_|); +} -$x = $C->_new("81"); -is ($C->_str($C->_pow($x,$n)),81 ** 3); -is ($C->_str($C->_pow($x,$n)),'150094635296999121'); # 531441 ** 3 == +# _sqrt -is ($C->_str($C->_root($x,$n)),'531441'); -is ($C->_str($C->_root($x,$n)),'81'); +$x = $LIB->_new("144"); +is($LIB->_str($LIB->_sqrt($x)), "12", + qq|$LIB->_str($LIB->_sqrt(\$x)) = "12"|); +$x = $LIB->_new("144000000000000"); +is($LIB->_str($LIB->_sqrt($x)), "12000000", + qq|$LIB->_str($LIB->_sqrt(\$x)) = "12000000"|); -$x = $C->_new("81"); $n = $C->_new("14"); -is ($C->_str($C->_pow($x,$n)),'523347633027360537213511521'); -is ($C->_str($C->_root($x,$n)),'81'); +# _root -$x = $C->_new("523347633027360537213511520"); -is ($C->_str($C->_root($x,$n)),'80'); +$x = $LIB->_new("81"); +my $n = $LIB->_new("3"); # 4*4*4 = 64, 5*5*5 = 125 +is($LIB->_str($LIB->_root($x, $n)), "4", + qq|$LIB->_str($LIB->_root(\$x, \$n)) = "4"|); # 4.xx => 4.0 -$x = $C->_new("523347633027360537213511522"); -is ($C->_str($C->_root($x,$n)),'81'); +$x = $LIB->_new("81"); +$n = $LIB->_new("4"); # 3*3*3*3 == 81 +is($LIB->_str($LIB->_root($x, $n)), "3", + qq|$LIB->_str($LIB->_root(\$x, \$n)) = "3"|); + +# _pow (and _root) -my $res = [ qw/ 9 31 99 316 999 3162 9999/ ]; +$x = $LIB->_new("0"); +$n = $LIB->_new("3"); # 0 ** y => 0 +is($LIB->_str($LIB->_pow($x, $n)), 0, + qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 0|); + +$x = $LIB->_new("3"); +$n = $LIB->_new("0"); # x ** 0 => 1 +is($LIB->_str($LIB->_pow($x, $n)), 1, + qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 1|); + +$x = $LIB->_new("1"); +$n = $LIB->_new("3"); # 1 ** y => 1 +is($LIB->_str($LIB->_pow($x, $n)), 1, + qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 1|); + +$x = $LIB->_new("5"); +$n = $LIB->_new("1"); # x ** 1 => x +is($LIB->_str($LIB->_pow($x, $n)), 5, + qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 5|); + +$x = $LIB->_new("81"); +$n = $LIB->_new("3"); # 81 ** 3 == 531441 +is($LIB->_str($LIB->_pow($x, $n)), 81 ** 3, + qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 81 ** 3|); + +is($LIB->_str($LIB->_root($x, $n)), 81, + qq|$LIB->_str($LIB->_root(\$x, \$n)) = 81|); + +$x = $LIB->_new("81"); +is($LIB->_str($LIB->_pow($x, $n)), 81 ** 3, + qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 81 ** 3|); +is($LIB->_str($LIB->_pow($x, $n)), "150094635296999121", # 531441 ** 3 + qq|$LIB->_str($LIB->_pow(\$x, \$n)) = "150094635296999121"|); + +is($LIB->_str($LIB->_root($x, $n)), "531441", + qq|$LIB->_str($LIB->_root(\$x, \$n)) = "531441"|); +is($LIB->_str($LIB->_root($x, $n)), "81", + qq|$LIB->_str($LIB->_root(\$x, \$n)) = "81"|); + +$x = $LIB->_new("81"); +$n = $LIB->_new("14"); +is($LIB->_str($LIB->_pow($x, $n)), "523347633027360537213511521", + qq|$LIB->_str($LIB->_pow(\$x, \$n)) = "523347633027360537213511521"|); +is($LIB->_str($LIB->_root($x, $n)), "81", + qq|$LIB->_str($LIB->_root(\$x, \$n)) = "81"|); + +$x = $LIB->_new("523347633027360537213511520"); +is($LIB->_str($LIB->_root($x, $n)), "80", + qq|$LIB->_str($LIB->_root(\$x, \$n)) = "80"|); + +$x = $LIB->_new("523347633027360537213511522"); +is($LIB->_str($LIB->_root($x, $n)), "81", + qq|$LIB->_str($LIB->_root(\$x, \$n)) = "81"|); + +my $res = [ qw/9 31 99 316 999 3162 9999 31622 99999/ ]; # 99 ** 2 = 9801, 999 ** 2 = 998001 etc -for my $i (2 .. 9) - { - $x = '9' x $i; $x = $C->_new($x); - $n = $C->_new("2"); - my $rc = '9' x ($i-1). '8' . '0' x ($i-1) . '1'; - print "# _pow( ", '9' x $i, ", 2) \n" unless - is ($C->_str($C->_pow($x,$n)),$rc); - - if ($i <= 7) - { - $x = '9' x $i; $x = $C->_new($x); - $n = '9' x $i; $n = $C->_new($n); - print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n" unless - is ($C->_str($C->_root($x,$n)),'1'); - - $x = '9' x $i; $x = $C->_new($x); - $n = $C->_new("2"); - print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n" unless - is ($C->_str($C->_root($x,$n)), $res->[$i-2]); + +for my $i (2 .. 9) { + $x = '9' x $i; + $x = $LIB->_new($x); + $n = $LIB->_new("2"); + my $rc = '9' x ($i-1). '8' . '0' x ($i - 1) . '1'; + print "# _pow( ", '9' x $i, ", 2) \n" unless + is($LIB->_str($LIB->_pow($x, $n)), $rc, + qq|$LIB->_str($LIB->_pow(\$x, \$n)) = $rc|); + + SKIP: { + # If $i > $BASE_LEN, the test takes a really long time. + skip "$i > $BASE_LEN", 2 unless $i <= $BASE_LEN; + + $x = '9' x $i; + $x = $LIB->_new($x); + $n = '9' x $i; + $n = $LIB->_new($n); + print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n"; + print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n" + unless is($LIB->_str($LIB->_root($x, $n)), '1', + qq|$LIB->_str($LIB->_root(\$x, \$n)) = '1'|); + + $x = '9' x $i; + $x = $LIB->_new($x); + $n = $LIB->_new("2"); + print "# BASE_LEN $BASE_LEN _root( ", '9' x $i, ", ", 9 x $i, ") \n" + unless is($LIB->_str($LIB->_root($x, $n)), $res->[$i-2], + qq|$LIB->_str($LIB->_root(\$x, \$n)) = $res->[$i-2]|); } - } +} ############################################################################## # _fac -$x = $C->_new("0"); is ($C->_str($C->_fac($x)),'1'); -$x = $C->_new("1"); is ($C->_str($C->_fac($x)),'1'); -$x = $C->_new("2"); is ($C->_str($C->_fac($x)),'2'); -$x = $C->_new("3"); is ($C->_str($C->_fac($x)),'6'); -$x = $C->_new("4"); is ($C->_str($C->_fac($x)),'24'); -$x = $C->_new("5"); is ($C->_str($C->_fac($x)),'120'); -$x = $C->_new("10"); is ($C->_str($C->_fac($x)),'3628800'); -$x = $C->_new("11"); is ($C->_str($C->_fac($x)),'39916800'); -$x = $C->_new("12"); is ($C->_str($C->_fac($x)),'479001600'); -$x = $C->_new("13"); is ($C->_str($C->_fac($x)),'6227020800'); + +$x = $LIB->_new("0"); +is($LIB->_str($LIB->_fac($x)), "1", + qq|$LIB->_str($LIB->_fac(\$x)) = "1"|); + +$x = $LIB->_new("1"); +is($LIB->_str($LIB->_fac($x)), "1", + qq|$LIB->_str($LIB->_fac(\$x)) = "1"|); + +$x = $LIB->_new("2"); +is($LIB->_str($LIB->_fac($x)), "2", + qq|$LIB->_str($LIB->_fac(\$x)) = "2"|); + +$x = $LIB->_new("3"); +is($LIB->_str($LIB->_fac($x)), "6", + qq|$LIB->_str($LIB->_fac(\$x)) = "6"|); + +$x = $LIB->_new("4"); +is($LIB->_str($LIB->_fac($x)), "24", + qq|$LIB->_str($LIB->_fac(\$x)) = "24"|); + +$x = $LIB->_new("5"); +is($LIB->_str($LIB->_fac($x)), "120", + qq|$LIB->_str($LIB->_fac(\$x)) = "120"|); + +$x = $LIB->_new("10"); +is($LIB->_str($LIB->_fac($x)), "3628800", + qq|$LIB->_str($LIB->_fac(\$x)) = "3628800"|); + +$x = $LIB->_new("11"); +is($LIB->_str($LIB->_fac($x)), "39916800", + qq|$LIB->_str($LIB->_fac(\$x)) = "39916800"|); + +$x = $LIB->_new("12"); +is($LIB->_str($LIB->_fac($x)), "479001600", + qq|$LIB->_str($LIB->_fac(\$x)) = "479001600"|); + +$x = $LIB->_new("13"); +is($LIB->_str($LIB->_fac($x)), "6227020800", + qq|$LIB->_str($LIB->_fac(\$x)) = "6227020800"|); # test that _fac modifies $x in place for small arguments -$x = $C->_new("3"); $C->_fac($x); is ($C->_str($x),'6'); -$x = $C->_new("13"); $C->_fac($x); is ($C->_str($x),'6227020800'); -############################################################################## +$x = $LIB->_new("3"); +$LIB->_fac($x); +is($LIB->_str($x), "6", + qq|$LIB->_str(\$x) = "6"|); + +$x = $LIB->_new("13"); +$LIB->_fac($x); +is($LIB->_str($x), "6227020800", + qq|$LIB->_str(\$x) = "6227020800"|); + # _inc and _dec -foreach (qw/1 11 121 1231 12341 1234561 12345671 123456781 1234567891/) - { - $x = $C->_new("$_"); $C->_inc($x); - print "# \$x = ",$C->_str($x),"\n" - unless is ($C->_str($x),substr($_,0,length($_)-1) . '2'); - $C->_dec($x); is ($C->_str($x),$_); - } -foreach (qw/19 119 1219 12319 1234519 12345619 123456719 1234567819/) - { - $x = $C->_new("$_"); $C->_inc($x); - print "# \$x = ",$C->_str($x),"\n" - unless is ($C->_str($x),substr($_,0,length($_)-2) . '20'); - $C->_dec($x); is ($C->_str($x),$_); - } -foreach (qw/999 9999 99999 9999999 99999999 999999999 9999999999 99999999999/) - { - $x = $C->_new("$_"); $C->_inc($x); - print "# \$x = ",$C->_str($x),"\n" - unless is ($C->_str($x), '1' . '0' x (length($_))); - $C->_dec($x); is ($C->_str($x),$_); - } - -$x = $C->_new("1000"); $C->_inc($x); is ($C->_str($x),'1001'); -$C->_dec($x); is ($C->_str($x),'1000'); - -my $BL = $C -> _base_len(); + +for (qw/1 11 121 1231 12341 1234561 12345671 123456781 1234567891/) { + $x = $LIB->_new("$_"); + $LIB->_inc($x); + my $expected = substr($_, 0, length($_) - 1) . '2'; + is($LIB->_str($x), $expected, qq|$LIB->_str(\$x) = $expected|); + $LIB->_dec($x); + is($LIB->_str($x), $_, qq|$LIB->_str(\$x) = $_|); +} + +for (qw/19 119 1219 12319 1234519 12345619 123456719 1234567819/) { + $x = $LIB->_new("$_"); + $LIB->_inc($x); + my $expected = substr($_, 0, length($_)-2) . '20'; + is($LIB->_str($x), $expected, qq|$LIB->_str(\$x) = $expected|); + $LIB->_dec($x); + is($LIB->_str($x), $_, qq|$LIB->_str(\$x) = $_|); +} + +for (1 .. 20) { + my $p = "9" x $_; # = $q - 1 + my $q = "1" . ("0" x $_); # = $p + 1 + + $x = $LIB->_new("$p"); + $LIB->_inc($x); + is($LIB->_str($x), $q, qq|\$x = $LIB->_new("$p"); $LIB->_inc()|); + + $x = $LIB->_new("$q"); + $LIB->_dec($x); + is($LIB->_str($x), $p, qq|\$x = $LIB->_new("$q"); $LIB->_dec()|); +} + +for (1 .. 20) { + my $p = "1" . ("0" x $_); # = $q - 1 + my $q = "1" . ("0" x ($_ - 1)) . "1"; # = $p + 1 + + $x = $LIB->_new("$p"); + $LIB->_inc($x); + is($LIB->_str($x), $q, qq|\$x = $LIB->_new("$p"); $LIB->_inc()|); + + $x = $LIB->_new("$q"); + $LIB->_dec($x); + is($LIB->_str($x), $p, qq|\$x = $LIB->_new("$q"); $LIB->_dec()|); +} + +$x = $LIB->_new("1000"); +$LIB->_inc($x); +is($LIB->_str($x), "1001", qq|$LIB->_str(\$x) = "1001"|); +$LIB->_dec($x); +is($LIB->_str($x), "1000", qq|$LIB->_str(\$x) = "1000"|); + +my $BL = $LIB -> _base_len(); $x = '1' . '0' x $BL; -$z = '1' . '0' x ($BL-1); $z .= '1'; -$x = $C->_new($x); $C->_inc($x); is ($C->_str($x),$z); +$z = '1' . '0' x ($BL - 1); +$z .= '1'; +$x = $LIB->_new($x); +$LIB->_inc($x); +is($LIB->_str($x), $z, qq|$LIB->_str(\$x) = $z|); -$x = '1' . '0' x $BL; $z = '9' x $BL; -$x = $C->_new($x); $C->_dec($x); is ($C->_str($x),$z); +$x = '1' . '0' x $BL; +$z = '9' x $BL; +$x = $LIB->_new($x); +$LIB->_dec($x); +is($LIB->_str($x), $z, qq|$LIB->_str(\$x) = $z|); # should not happen: -# $x = $C->_new("-2"); $y = $C->_new("4"); is ($C->_acmp($x,$y),-1); +# $x = $LIB->_new("-2"); +# $y = $LIB->_new("4"); +# is($LIB->_acmp($x, $y), -1, qq|$LIB->_acmp($x, $y) = -1|); ############################################################################### # _mod -$x = $C->_new("1000"); $y = $C->_new("3"); -is ($C->_str(scalar $C->_mod($x,$y)),1); -$x = $C->_new("1000"); $y = $C->_new("2"); -is ($C->_str(scalar $C->_mod($x,$y)),0); + +$x = $LIB->_new("1000"); +$y = $LIB->_new("3"); +is($LIB->_str(scalar($LIB->_mod($x, $y))), 1, + qq|$LIB->_str(scalar($LIB->_mod(\$x, \$y))) = 1|); + +$x = $LIB->_new("1000"); +$y = $LIB->_new("2"); +is($LIB->_str(scalar($LIB->_mod($x, $y))), 0, + qq|$LIB->_str(scalar($LIB->_mod(\$x, \$y))) = 0|); # _and, _or, _xor -$x = $C->_new("5"); $y = $C->_new("2"); -is ($C->_str(scalar $C->_xor($x,$y)),7); -$x = $C->_new("5"); $y = $C->_new("2"); -is ($C->_str(scalar $C->_or($x,$y)),7); -$x = $C->_new("5"); $y = $C->_new("3"); -is ($C->_str(scalar $C->_and($x,$y)),1); + +$x = $LIB->_new("5"); +$y = $LIB->_new("2"); +is($LIB->_str(scalar($LIB->_xor($x, $y))), 7, + qq|$LIB->_str(scalar($LIB->_xor(\$x, \$y))) = 7|); + +$x = $LIB->_new("5"); +$y = $LIB->_new("2"); +is($LIB->_str(scalar($LIB->_or($x, $y))), 7, + qq|$LIB->_str(scalar($LIB->_or(\$x, \$y))) = 7|); + +$x = $LIB->_new("5"); +$y = $LIB->_new("3"); +is($LIB->_str(scalar($LIB->_and($x, $y))), 1, + qq|$LIB->_str(scalar($LIB->_and(\$x, \$y))) = 1|); # _from_hex, _from_bin, _from_oct -is ($C->_str( $C->_from_hex("0xFf")),255); -is ($C->_str( $C->_from_bin("0b10101011")),160+11); -is ($C->_str( $C->_from_oct("0100")), 8*8); -is ($C->_str( $C->_from_oct("01000")), 8*8*8); -is ($C->_str( $C->_from_oct("010001")), 8*8*8*8+1); -is ($C->_str( $C->_from_oct("010007")), 8*8*8*8+7); + +is($LIB->_str($LIB->_from_hex("0xFf")), 255, + qq|$LIB->_str($LIB->_from_hex("0xFf")) = 255|); +is($LIB->_str($LIB->_from_bin("0b10101011")), 160+11, + qq|$LIB->_str($LIB->_from_bin("0b10101011")) = 160+11|); +is($LIB->_str($LIB->_from_oct("0100")), 8*8, + qq|$LIB->_str($LIB->_from_oct("0100")) = 8*8|); +is($LIB->_str($LIB->_from_oct("01000")), 8*8*8, + qq|$LIB->_str($LIB->_from_oct("01000")) = 8*8*8|); +is($LIB->_str($LIB->_from_oct("010001")), 8*8*8*8+1, + qq|$LIB->_str($LIB->_from_oct("010001")) = 8*8*8*8+1|); +is($LIB->_str($LIB->_from_oct("010007")), 8*8*8*8+7, + qq|$LIB->_str($LIB->_from_oct("010007")) = 8*8*8*8+7|); # _as_hex, _as_bin, as_oct -is ($C->_str( $C->_from_hex( $C->_as_hex( $C->_new("128")))), 128); -is ($C->_str( $C->_from_bin( $C->_as_bin( $C->_new("128")))), 128); -is ($C->_str( $C->_from_oct( $C->_as_oct( $C->_new("128")))), 128); -is ($C->_str( $C->_from_oct( $C->_as_oct( $C->_new("123456")))), 123456); -is ($C->_str( $C->_from_oct( $C->_as_oct( $C->_new("123456789")))), "123456789"); -is ($C->_str( $C->_from_oct( $C->_as_oct( $C->_new("1234567890123")))), "1234567890123"); +is($LIB->_str($LIB->_from_hex($LIB->_as_hex($LIB->_new("128")))), 128, + qq|$LIB->_str($LIB->_from_hex($LIB->_as_hex(| + . qq|$LIB->_new("128")))) = 128|); +is($LIB->_str($LIB->_from_bin($LIB->_as_bin($LIB->_new("128")))), 128, + qq|$LIB->_str($LIB->_from_bin($LIB->_as_bin(| + . qq|$LIB->_new("128")))) = 128|); +is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("128")))), 128, + qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| + . qq|$LIB->_new("128")))) = 128|); + +is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("123456")))), + 123456, + qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct| + . qq|($LIB->_new("123456")))) = 123456|); +is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("123456789")))), + "123456789", + qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| + . qq|$LIB->_new("123456789")))) = "123456789"|); +is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("1234567890123")))), + "1234567890123", + qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| + . qq|$LIB->_new("1234567890123")))) = "1234567890123"|); + +my $long = "123456789012345678901234567890"; +is($LIB->_str($LIB->_from_hex($LIB->_as_hex($LIB->_new($long)))), $long, + qq|$LIB->_str($LIB->_from_hex($LIB->_as_hex(| + . qq|$LIB->_new("$long")))) = "$long"|); +is($LIB->_str($LIB->_from_bin($LIB->_as_bin($LIB->_new($long)))), $long, + qq|$LIB->_str($LIB->_from_bin($LIB->_as_bin(| + . qq|$LIB->_new("$long")))) = "$long"|); +is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new($long)))), $long, + qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| + . qq|$LIB->_new("$long")))) = "$long"|); + +is($LIB->_str($LIB->_from_hex($LIB->_as_hex($LIB->_new("0")))), 0, + qq|$LIB->_str($LIB->_from_hex($LIB->_as_hex(| + . qq|$LIB->_new("0")))) = 0|); +is($LIB->_str($LIB->_from_bin($LIB->_as_bin($LIB->_new("0")))), 0, + qq|$LIB->_str($LIB->_from_bin($LIB->_as_bin(| + . qq|$LIB->_new("0")))) = 0|); +is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("0")))), 0, + qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| + . qq|$LIB->_new("0")))) = 0|); + +is($LIB->_as_hex($LIB->_new("0")), "0x0", + qq|$LIB->_as_hex($LIB->_new("0")) = "0x0"|); +is($LIB->_as_bin($LIB->_new("0")), "0b0", + qq|$LIB->_as_bin($LIB->_new("0")) = "0b0"|); +is($LIB->_as_oct($LIB->_new("0")), "00", + qq|$LIB->_as_oct($LIB->_new("0")) = "00"|); + +is($LIB->_as_hex($LIB->_new("12")), "0xc", + qq|$LIB->_as_hex($LIB->_new("12")) = "0xc"|); +is($LIB->_as_bin($LIB->_new("12")), "0b1100", + qq|$LIB->_as_bin($LIB->_new("12")) = "0b1100"|); +is($LIB->_as_oct($LIB->_new("64")), "0100", + qq|$LIB->_as_oct($LIB->_new("64")) = "0100"|); # _1ex -is ($C->_str($C->_1ex(0)), "1"); -is ($C->_str($C->_1ex(1)), "10"); -is ($C->_str($C->_1ex(2)), "100"); -is ($C->_str($C->_1ex(12)), "1000000000000"); -is ($C->_str($C->_1ex(16)), "10000000000000000"); + +is($LIB->_str($LIB->_1ex(0)), "1", + qq|$LIB->_str($LIB->_1ex(0)) = "1"|); +is($LIB->_str($LIB->_1ex(1)), "10", + qq|$LIB->_str($LIB->_1ex(1)) = "10"|); +is($LIB->_str($LIB->_1ex(2)), "100", + qq|$LIB->_str($LIB->_1ex(2)) = "100"|); +is($LIB->_str($LIB->_1ex(12)), "1000000000000", + qq|$LIB->_str($LIB->_1ex(12)) = "1000000000000"|); +is($LIB->_str($LIB->_1ex(16)), "10000000000000000", + qq|$LIB->_str($LIB->_1ex(16)) = "10000000000000000"|); # _check -$x = $C->_new("123456789"); -is ($C->_check($x),0); -is ($C->_check(123),'123 is not a reference'); + +$x = $LIB->_new("123456789"); +is($LIB->_check($x), 0, + qq|$LIB->_check(\$x) = 0|); +is($LIB->_check(123), "123 is not a reference", + qq|$LIB->_check(123) = "123 is not a reference"|); ############################################################################### # __strip_zeros { - no strict 'refs'; - # correct empty arrays - $x = &{$C."::__strip_zeros"}([]); is (@$x,1); is ($x->[0],0); - # don't strip single elements - $x = &{$C."::__strip_zeros"}([0]); is (@$x,1); is ($x->[0],0); - $x = &{$C."::__strip_zeros"}([1]); is (@$x,1); is ($x->[0],1); - # don't strip non-zero elements - $x = &{$C."::__strip_zeros"}([0,1]); - is (@$x,2); is ($x->[0],0); is ($x->[1],1); - $x = &{$C."::__strip_zeros"}([0,1,2]); - is (@$x,3); is ($x->[0],0); is ($x->[1],1); is ($x->[2],2); - - # but strip leading zeros - $x = &{$C."::__strip_zeros"}([0,1,2,0]); - is (@$x,3); is ($x->[0],0); is ($x->[1],1); is ($x->[2],2); - - $x = &{$C."::__strip_zeros"}([0,1,2,0,0]); - is (@$x,3); is ($x->[0],0); is ($x->[1],1); is ($x->[2],2); - - $x = &{$C."::__strip_zeros"}([0,1,2,0,0,0]); - is (@$x,3); is ($x->[0],0); is ($x->[1],1); is ($x->[2],2); - - # collapse multiple zeros - $x = &{$C."::__strip_zeros"}([0,0,0,0]); - is (@$x,1); is ($x->[0],0); + no strict 'refs'; + + # correct empty arrays + $x = &{$LIB."::__strip_zeros"}([]); + is(@$x, 1, q|@$x = 1|); + is($x->[0], 0, q|$x->[0] = 0|); + + # don't strip single elements + $x = &{$LIB."::__strip_zeros"}([0]); + is(@$x, 1, q|@$x = 1|); + is($x->[0], 0, q|$x->[0] = 0|); + $x = &{$LIB."::__strip_zeros"}([1]); + is(@$x, 1, q|@$x = 1|); + is($x->[0], 1, q|$x->[0] = 1|); + + # don't strip non-zero elements + $x = &{$LIB."::__strip_zeros"}([0, 1]); + is(@$x, 2, q|@$x = 2|); + is($x->[0], 0, q|$x->[0] = 0|); + is($x->[1], 1, q|$x->[1] = 1|); + $x = &{$LIB."::__strip_zeros"}([0, 1, 2]); + is(@$x, 3, q|@$x = 3|); + is($x->[0], 0, q|$x->[0] = 0|); + is($x->[1], 1, q|$x->[1] = 1|); + is($x->[2], 2, q|$x->[2] = 2|); + + # but strip leading zeros + $x = &{$LIB."::__strip_zeros"}([0, 1, 2, 0]); + is(@$x, 3, q|@$x = 3|); + is($x->[0], 0, q|$x->[0] = 0|); + is($x->[1], 1, q|$x->[1] = 1|); + is($x->[2], 2, q|$x->[2] = 2|); + + $x = &{$LIB."::__strip_zeros"}([0, 1, 2, 0, 0]); + is(@$x, 3, q|@$x = 3|); + is($x->[0], 0, q|$x->[0] = 0|); + is($x->[1], 1, q|$x->[1] = 1|); + is($x->[2], 2, q|$x->[2] = 2|); + + $x = &{$LIB."::__strip_zeros"}([0, 1, 2, 0, 0, 0]); + is(@$x, 3, q|@$x = 3|); + is($x->[0], 0, q|$x->[0] = 0|); + is($x->[1], 1, q|$x->[1] = 1|); + is($x->[2], 2, q|$x->[2] = 2|); + + # collapse multiple zeros + $x = &{$LIB."::__strip_zeros"}([0, 0, 0, 0]); + is(@$x, 1, q|@$x = 1|); + is($x->[0], 0, q|$x->[0] = 0|); } - -# done - -1; diff --git a/cpan/Math-BigInt/lib/Math/BigFloat.pm b/cpan/Math-BigInt/lib/Math/BigFloat.pm index f1d7a1a0a0..5dcc919e1a 100644 --- a/cpan/Math-BigInt/lib/Math/BigFloat.pm +++ b/cpan/Math-BigInt/lib/Math/BigFloat.pm @@ -19,7 +19,7 @@ use warnings; use Carp qw< carp croak >; use Math::BigInt (); -our $VERSION = '1.999818'; +our $VERSION = '1.999823'; require Exporter; our @ISA = qw/Math::BigInt/; @@ -417,17 +417,18 @@ sub new { return $self; } - # Handle hexadecimal numbers. We auto-detect hexadecimal numbers if they - # have a "0x" or "0X" prefix. + # Handle hexadecimal numbers. Just like CORE::oct(), we accept octal numbers with + # prefix "0x", "0X", "x", or "X". - if ($wanted =~ /^\s*[+-]?0[Xx]/) { + if ($wanted =~ /^\s*[+-]?0?[Xx]/) { $self = $class -> from_hex($wanted); $self->round(@r) unless @r >= 2 && !defined $r[0] && !defined $r[1]; return $self; } - # Handle octal numbers. We auto-detect octal numbers if they have a "0" - # prefix and a binary exponent. + # Handle octal numbers. Just like CORE::oct(), we accept octal numbers with + # prefix "0o", "0O", "o", or "O". If the prefix is just "0", the number must + # have a binary exponent, or else the number is interpreted as decimal. if ($wanted =~ / ^ @@ -436,23 +437,28 @@ sub new { # sign [+-]? - # prefix - 0 - - # significand using the octal digits 0..7 - [0-7]+ (?: _ [0-7]+ )* (?: - \. - (?: [0-7]+ (?: _ [0-7]+ )* )? - )? - - # exponent (power of 2) using decimal digits - [Pp] - [+-]? - \d+ (?: _ \d+ )* - - \s* - $ + # prefix + 0? [Oo] + | + + # prefix + 0 + + # significand using the octal digits 0..7 + [0-7]+ (?: _ [0-7]+ )* + (?: + \. + (?: [0-7]+ (?: _ [0-7]+ )* )? + )? + + # exponent (power of 2) using decimal digits + [Pp] + [+-]? + \d+ (?: _ \d+ )* + \s* + $ + ) /x) { $self = $class -> from_oct($wanted); @@ -460,10 +466,10 @@ sub new { return $self; } - # Handle binary numbers. We auto-detect binary numbers if they have a "0b" - # or "0B" prefix. + # Handle binary numbers. Just like CORE::oct(), we accept octal numbers with + # prefix "0b", "0B", "b", or "B". - if ($wanted =~ /^\s*[+-]?0[Bb]/) { + if ($wanted =~ /^\s*[+-]?0?[Bb]/) { $self = $class -> from_bin($wanted); $self->round(@r) unless @r >= 2 && !defined $r[0] && !defined $r[1]; return $self; @@ -571,8 +577,8 @@ sub from_hex { # sign ( [+-]? ) - # optional "hex marker" - (?: 0? x )? + # optional hexadecimal prefix + (?: 0? [Xx] )? # significand using the hex digits 0..9 and a..f ( @@ -662,6 +668,9 @@ sub from_oct { # sign ( [+-]? ) + # optional octal prefix + (?: 0? [Oo] )? + # significand using the octal digits 0..7 ( [0-7]+ (?: _ [0-7]+ )* @@ -750,8 +759,8 @@ sub from_bin { # sign ( [+-]? ) - # optional "bin marker" - (?: 0? b )? + # optional binary prefix + (?: 0? [Bb] )? # significand using the binary digits 0 and 1 ( @@ -2794,7 +2803,7 @@ sub bsin { # constant object or error in _find_round_parameters? return $x if $x->modify('bsin') || $x->is_nan(); - + return $x->bnan() if $x->is_inf(); return $x->bzero(@r) if $x->is_zero(); # no rounding at all, so must use fallback @@ -2884,7 +2893,7 @@ sub bcos { # constant object or error in _find_round_parameters? return $x if $x->modify('bcos') || $x->is_nan(); - + return $x->bnan() if $x->is_inf(); return $x->bone(@r) if $x->is_zero(); # no rounding at all, so must use fallback @@ -3519,11 +3528,12 @@ sub bdfac { ($class, $x, @r) = objectify(1, @_) if !ref($x); # inf => inf - return $x if $x->modify('bfac') || $x->{sign} eq '+inf'; + return $x if $x->modify('bdfac') || $x->{sign} eq '+inf'; - return $x->bnan() - if (($x->{sign} ne '+') || # inf, NaN, <0 etc => NaN - ($x->{_es} ne '+')); # digits after dot? + return $x->bnan() if ($x->is_nan() || + $x->{_es} ne '+'); # digits after dot? + return $x->bnan() if $x <= -2; + return $x->bone() if $x <= 1; croak("bdfac() requires a newer version of the $LIB library.") unless $LIB->can('_dfac'); @@ -3537,6 +3547,55 @@ sub bdfac { $x->bnorm()->round(@r); # norm again and round result } +sub btfac { + # compute triple factorial + + # set up parameters + my ($class, $x, @r) = (ref($_[0]), @_); + # objectify is costly, so avoid it + ($class, $x, @r) = objectify(1, @_) if !ref($x); + + # inf => inf + return $x if $x->modify('btfac') || $x->{sign} eq '+inf'; + + return $x->bnan() if ($x->is_nan() || + $x->{_es} ne '+'); # digits after dot? + + my $k = $class -> new("3"); + return $x->bnan() if $x <= -$k; + + my $one = $class -> bone(); + return $x->bone() if $x <= $one; + + my $f = $x -> copy(); + while ($f -> bsub($k) > $one) { + $x -> bmul($f); + } + $x->round(@r); +} + +sub bmfac { + my ($class, $x, $k, @r) = objectify(2, @_); + + # inf => inf + return $x if $x->modify('bmfac') || $x->{sign} eq '+inf'; + + return $x->bnan() if ($x->is_nan() || $k->is_nan() || + $k < 1 || $x <= -$k || + $x->{_es} ne '+' || $k->{_es} ne '+'); + + return $x->bnan() if $x <= -$k; + + my $one = $class -> bone(); + return $x->bone() if $x <= $one; + + my $f = $x -> copy(); + while ($f -> bsub($k) > $one) { + $x -> bmul($f); + } + $x->round(@r); +} + sub blsft { # shift left by $y (multiply by $b ** $y) @@ -4042,7 +4101,7 @@ sub sparts { # Finite number. - my $mant = $class -> bzero(); + my $mant = $self -> copy() -> bzero(); $mant -> {sign} = $self -> {sign}; $mant -> {_m} = $LIB->_copy($self -> {_m}); return $mant unless wantarray; @@ -4605,13 +4664,13 @@ sub numify { if ($x -> is_nan()) { require Math::Complex; - my $inf = Math::Complex::Inf(); + my $inf = $Math::Complex::Inf; return $inf - $inf; } if ($x -> is_inf()) { require Math::Complex; - my $inf = Math::Complex::Inf(); + my $inf = $Math::Complex::Inf; return $x -> is_negative() ? -$inf : $inf; } @@ -4625,66 +4684,60 @@ sub numify { sub import { my $class = shift; - my $l = scalar @_; + $IMPORT++; # remember we did import() + my @a; # unrecognized arguments my $lib = ''; - my @a; my $lib_kind = 'try'; - $IMPORT=1; - for (my $i = 0; $i < $l ; $i++) { + + for (my $i = 0; $i <= $#_ ; $i++) { + croak "Error in import(): argument with index $i is undefined" + unless defined($_[$i]); + if ($_[$i] eq ':constant') { # This causes overlord er load to step in. 'binary' and 'integer' # are handled by BigInt. overload::constant float => sub { $class->new(shift); }; - } elsif ($_[$i] eq 'upgrade') { + } + + elsif ($_[$i] eq 'upgrade') { # this causes upgrading - $upgrade = $_[$i+1]; # or undef to disable + $upgrade = $_[$i+1]; # or undef to disable $i++; - } elsif ($_[$i] eq 'downgrade') { + } + + elsif ($_[$i] eq 'downgrade') { # this causes downgrading - $downgrade = $_[$i+1]; # or undef to disable + $downgrade = $_[$i+1]; # or undef to disable $i++; - } elsif ($_[$i] =~ /^(lib|try|only)\z/) { + } + + elsif ($_[$i] =~ /^(lib|try|only)\z/) { # alternative library - $lib = $_[$i+1] || ''; # default Calc - $lib_kind = $1; # lib, try or only + $lib = $_[$i+1] || ''; + $lib_kind = $1; # "lib", "try", or "only" $i++; - } elsif ($_[$i] eq 'with') { + } + + elsif ($_[$i] eq 'with') { # alternative class for our private parts() # XXX: no longer supported - # $LIB = $_[$i+1] || 'Math::BigInt'; + # $LIB = $_[$i+1] || 'Calc'; + # carp "'with' is no longer supported, use 'lib', 'try', or 'only'"; $i++; - } else { + } + + else { push @a, $_[$i]; } } - $lib =~ tr/a-zA-Z0-9,://cd; # restrict to sane characters - # let use Math::BigInt lib => 'GMP'; use Math::BigFloat; still work - my $mbilib = eval { Math::BigInt->config('lib') }; - if ((defined $mbilib) && ($LIB eq 'Math::BigInt::Calc')) { - # $LIB already loaded - Math::BigInt->import($lib_kind, "$lib, $mbilib", 'objectify'); - } else { - # $LIB not loaded, or with ne "Math::BigInt::Calc" - $lib .= ",$mbilib" if defined $mbilib; - $lib =~ s/^,//; # don't leave empty - - # replacement library can handle lib statement, but also could ignore it + my @import = ('objectify'); + push @import, $lib_kind, $lib if $lib ne ''; + Math::BigInt -> import(@import); - # Perl < 5.6.0 dies with "out of memory!" when eval() and ':constant' is - # used in the same script, or eval inside import(). So we require MBI: - require Math::BigInt; - Math::BigInt->import($lib_kind => $lib, 'objectify'); - } - if ($@) { - croak("Couldn't load $lib: $! $@"); - } # find out which one was actually loaded $LIB = Math::BigInt->config('lib'); - # register us with MBI to get notified of future lib changes - Math::BigInt::_register_callback($class, sub { $LIB = $_[0]; }); - $class->export_to_level(1, $class, @a); # export wanted functions } @@ -5169,10 +5222,13 @@ Math::BigFloat - Arbitrary size floating point math package $x = Math::BigFloat->new($str); # defaults to 0 $x = Math::BigFloat->new('0x123'); # from hexadecimal + $x = Math::BigFloat->new('0o377'); # from octal $x = Math::BigFloat->new('0b101'); # from binary $x = Math::BigFloat->from_hex('0xc.afep+3'); # from hex $x = Math::BigFloat->from_hex('cafe'); # ditto $x = Math::BigFloat->from_oct('1.3267p-4'); # from octal + $x = Math::BigFloat->from_oct('01.3267p-4'); # ditto + $x = Math::BigFloat->from_oct('0o1.3267p-4'); # ditto $x = Math::BigFloat->from_oct('0377'); # ditto $x = Math::BigFloat->from_bin('0b1.1001p-4'); # from binary $x = Math::BigFloat->from_bin('0101'); # ditto @@ -5340,7 +5396,10 @@ Leading and trailing whitespace is ignored. =item * -Leading and trailing zeros are ignored. +Leading zeros are ignored, except for floating point numbers with a binary +exponent, in which case the number is interpreted as an octal floating point +number. For example, "01.4p+0" gives 1.5, "00.4p+0" gives 0.5, but "0.4p+0" +gives a NaN. And while "0377" gives 255, "0377p0" gives 255. =item * @@ -5348,28 +5407,27 @@ If the string has a "0x" prefix, it is interpreted as a hexadecimal number. =item * -If the string has a "0b" prefix, it is interpreted as a binary number. +If the string has a "0o" prefix, it is interpreted as an octal number. =item * -For hexadecimal and binary numbers, the exponent must be separated from the -significand (mantissa) by the letter "p" or "P", not "e" or "E" as with decimal -numbers. +If the string has a "0b" prefix, it is interpreted as a binary number. =item * -One underline is allowed between any two digits, including hexadecimal and -binary digits. +One underline is allowed between any two digits. =item * If the string can not be interpreted, NaN is returned. -=back +=item * -Octal numbers are typically prefixed by "0", but since leading zeros are -stripped, these methods can not automatically recognize octal numbers, so use -the constructor from_oct() to interpret octal strings. +For hexadecimal, octal, and binary numbers, the exponent must be separated from +the significand (mantissa) by the letter "p" or "P", not "e" or "E" as with +decimal numbers. + +=back Some examples of valid string input @@ -5378,10 +5436,16 @@ Some examples of valid string input 1.23e2 123 12300e-2 123 0xcafe 51966 + 0XCAFE 51966 + 0o1337 735 + 0O1337 735 0b1101 13 + 0B1101 13 67_538_754 67538754 -4_5_6.7_8_9e+0_1_0 -4567890000000 0x1.921fb5p+1 3.14159262180328369140625e+0 + 0o1.2677025p1 2.71828174591064453125 + 01.2677025p1 2.71828174591064453125 0b1.1001p-4 9.765625e-2 =head2 Output @@ -5944,8 +6008,7 @@ influence any further operation. Please report any bugs or feature requests to C<bug-math-bigint at rt.cpan.org>, or through the web interface at -L<https://rt.cpan.org/Ticket/Create.html?Queue=Math-BigInt> -(requires login). +L<https://rt.cpan.org/Ticket/Create.html?Queue=Math-BigInt> (requires login). We will be notified, and then you'll automatically be notified of progress on your bug as I make changes. @@ -5959,17 +6022,13 @@ You can also look for information at: =over 4 -=item * RT: CPAN's request tracker - -L<https://rt.cpan.org/Public/Dist/Display.html?Name=Math-BigInt> +=item * GitHub -=item * AnnoCPAN: Annotated CPAN documentation +L<https://github.com/pjacklam/p5-Math-BigInt> -L<http://annocpan.org/dist/Math-BigInt> - -=item * CPAN Ratings +=item * RT: CPAN's request tracker -L<https://cpanratings.perl.org/dist/Math-BigInt> +L<https://rt.cpan.org/Dist/Display.html?Name=Math-BigInt> =item * MetaCPAN @@ -5979,6 +6038,10 @@ L<https://metacpan.org/release/Math-BigInt> L<http://matrix.cpantesters.org/?dist=Math-BigInt> +=item * CPAN Ratings + +L<https://cpanratings.perl.org/dist/Math-BigInt> + =item * The Bignum mailing list =over 4 @@ -6006,7 +6069,7 @@ the same terms as Perl itself. =head1 SEE ALSO -L<Math::BigFloat> and L<Math::BigInt> as well as the backends +L<Math::BigInt> and L<Math::BigInt> as well as the backends L<Math::BigInt::FastCalc>, L<Math::BigInt::GMP>, and L<Math::BigInt::Pari>. The pragmas L<bignum>, L<bigint> and L<bigrat> also might be of interest @@ -6030,7 +6093,7 @@ Florian Ragwitz E<lt>flora@cpan.orgE<gt>, 2010. =item * -Peter John Acklam E<lt>pjacklam@online.noE<gt>, 2011-. +Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2011-. =back diff --git a/cpan/Math-BigInt/lib/Math/BigInt.pm b/cpan/Math-BigInt/lib/Math/BigInt.pm index 185f802835..82d289752e 100644 --- a/cpan/Math-BigInt/lib/Math/BigInt.pm +++ b/cpan/Math-BigInt/lib/Math/BigInt.pm @@ -22,7 +22,7 @@ use warnings; use Carp qw< carp croak >; -our $VERSION = '1.999818'; +our $VERSION = '1.999823'; require Exporter; our @ISA = qw(Exporter); @@ -228,11 +228,11 @@ our $_trap_inf = 0; # are infs ok? set w/ config() my $nan = 'NaN'; # constants for easier life -my $LIB = 'Math::BigInt::Calc'; # module to do the low level math +my $DEFAULT_LIB = 'Math::BigInt::Calc'; +my $LIB; # module to do the low level math # default is Calc.pm my $IMPORT = 0; # was import() called yet? # used to make require work -my %CALLBACKS; # callbacks to notify on lib loads ############################################################################## # the old code had $rnd_mode, so we need to support it, too @@ -613,17 +613,28 @@ sub new { return $self; } - # Handle hexadecimal numbers. + # Handle hexadecimal numbers. We auto-detect hexadecimal numbers if they + # have a "0x", "0X", "x", or "X" prefix, cf. CORE::oct(). - if ($wanted =~ /^\s*[+-]?0[Xx]/) { + if ($wanted =~ /^\s*[+-]?0?[Xx]/) { $self = $class -> from_hex($wanted); $self->round($a, $p, $r) unless @_ >= 3 && !defined $a && !defined $p; return $self; } - # Handle binary numbers. + # Handle octal numbers. We auto-detect octal numbers if they have a "0o", + # "0O", "o", "O" prefix, cf. CORE::oct(). - if ($wanted =~ /^\s*[+-]?0[Bb]/) { + if ($wanted =~ /^\s*[+-]?0?[Oo]/) { + $self = $class -> from_oct($wanted); + $self->round($a, $p, $r) unless @_ >= 3 && !defined $a && !defined $p; + return $self; + } + + # Handle binary numbers. We auto-detect binary numbers if they have a "0b", + # "B", "b", or "B" prefix, cf. CORE::oct(). + + if ($wanted =~ /^\s*[+-]?0?[Bb]/) { $self = $class -> from_bin($wanted); $self->round($a, $p, $r) unless @_ >= 3 && !defined $a && !defined $p; return $self; @@ -730,7 +741,7 @@ sub from_hex { ^ \s* ( [+-]? ) - (0?x)? + ( 0? [Xx] )? ( [0-9a-fA-F]* ( _ [0-9a-fA-F]+ )* @@ -786,6 +797,7 @@ sub from_oct { ^ \s* ( [+-]? ) + ( 0? [Oo] )? ( [0-7]* ( _ [0-7]+ )* @@ -798,7 +810,7 @@ sub from_oct { # underscores or invalid characters. my $sign = $1; - my $chrs = $2; + my $chrs = $3; $chrs =~ tr/_//d; $chrs = '0' unless CORE::length $chrs; @@ -841,7 +853,7 @@ sub from_bin { ^ \s* ( [+-]? ) - (0?b)? + ( 0? [Bb] )? ( [01]* ( _ [01]+ )* @@ -945,6 +957,46 @@ sub from_base { return $self } +sub from_base_num { + my $self = shift; + my $selfref = ref $self; + my $class = $selfref || $self; + + # Don't modify constant (read-only) objects. + + return if $selfref && $self->modify('from_base_num'); + + # Make sure we have an array of non-negative, finite, numerical objects. + + my $nums = shift; + $nums = [ @$nums ]; # create new reference + + for my $i (0 .. $#$nums) { + # Make sure we have an object. + $nums -> [$i] = $class -> new($nums -> [$i]) + unless ref($nums -> [$i]) && $nums -> [$i] -> isa($class); + # Make sure we have a finite, non-negative integer. + croak "the elements must be finite non-negative integers" + if $nums -> [$i] -> is_neg() || ! $nums -> [$i] -> is_int(); + } + + my $base = shift; + $base = $class -> new($base) unless ref($base) && $base -> isa($class); + + # If called as a class method, initialize a new object. + + $self = $class -> bzero() unless $selfref; + + croak("from_base_num() requires a newer version of the $LIB library.") + unless $LIB->can('_from_base_num'); + + $self -> {sign} = '+'; + $self -> {value} = $LIB -> _from_base_num([ map { $_ -> {value} } @$nums ], + $base -> {value}); + + return $self; +} + sub bzero { # create/assign '+0' @@ -2895,7 +2947,7 @@ sub bfac { my ($class, $x, @r) = ref($_[0]) ? (undef, @_) : objectify(1, @_); return $x if $x->modify('bfac') || $x->{sign} eq '+inf'; # inf => inf - return $x->bnan() if $x->{sign} ne '+'; # NaN, <0 etc => NaN + return $x->bnan() if $x->{sign} ne '+'; # NaN, <0 => NaN $x->{value} = $LIB->_fac($x->{value}); $x->round(@r); @@ -2906,7 +2958,8 @@ sub bdfac { my ($class, $x, @r) = ref($_[0]) ? (undef, @_) : objectify(1, @_); return $x if $x->modify('bdfac') || $x->{sign} eq '+inf'; # inf => inf - return $x->bnan() if $x->{sign} ne '+'; # NaN, <0 etc => NaN + return $x->bnan() if $x->is_nan() || $x <= -2; + return $x->bone() if $x <= 1; croak("bdfac() requires a newer version of the $LIB library.") unless $LIB->can('_dfac'); @@ -2915,6 +2968,44 @@ sub bdfac { $x->round(@r); } +sub btfac { + # compute triple factorial, modify $x in place + my ($class, $x, @r) = objectify(1, @_); + + return $x if $x->modify('btfac') || $x->{sign} eq '+inf'; # inf => inf + + return $x->bnan() if $x->is_nan(); + + my $k = $class -> new("3"); + return $x->bnan() if $x <= -$k; + + my $one = $class -> bone(); + return $x->bone() if $x <= $one; + + my $f = $x -> copy(); + while ($f -> bsub($k) > $one) { + $x -> bmul($f); + } + $x->round(@r); +} + +sub bmfac { + # compute multi-factorial + my ($class, $x, $k, @r) = objectify(2, @_); + + return $x if $x->modify('bmfac') || $x->{sign} eq '+inf'; + return $x->bnan() if $x->is_nan() || $k->is_nan() || $k < 1 || $x <= -$k; + + my $one = $class -> bone(); + return $x->bone() if $x <= $one; + + my $f = $x -> copy(); + while ($f -> bsub($k) > $one) { + $x -> bmul($f); + } + $x->round(@r); +} + sub bfib { # compute Fibonacci number(s) my ($class, $x, @r) = objectify(1, @_); @@ -3352,6 +3443,7 @@ sub bround { if (($pad > 0) && ($pad <= $len)) { substr($xs, -$pad, $pad) = '0' x $pad; # replace with '00...' + $xs =~ s/^0+(\d)/$1/; # "00000" -> "0" $put_back = 1; # need to put back } elsif ($pad > $len) { $x->bzero(); # round to '0' @@ -3373,7 +3465,6 @@ sub bround { last if $c != 0; # no overflow => early out } $xs = '1'.$xs if $c == 0; - } $x->{value} = $LIB->_new($xs) if $put_back == 1; # put back, if needed @@ -3895,6 +3986,37 @@ sub to_base { return $LIB->_to_base($x->{value}, $base -> {value}, @_ ? shift() : ()); } +sub to_base_num { + my $x = shift; + my $class = ref $x; + + # return a base anything string + croak("the value to convert must be a finite non-negative integer") + if $x -> is_neg() || !$x -> is_int(); + + my $base = shift; + $base = $class -> new($base) unless ref $base; + + croak("the base must be a finite integer >= 2") + if $base < 2 || ! $base -> is_int(); + + croak("to_base() requires a newer version of the $LIB library.") + unless $LIB->can('_to_base'); + + # Get a reference to an array of library thingies, and replace each element + # with a Math::BigInt object using that thingy. + + my $vals = $LIB -> _to_base_num($x->{value}, $base -> {value}); + + for my $i (0 .. $#$vals) { + my $x = $class -> bzero(); + $x -> {value} = $vals -> [$i]; + $vals -> [$i] = $x; + } + + return $vals; +} + sub as_hex { # return as hex string, with prefixed 0x my $x = shift; @@ -3941,13 +4063,13 @@ sub numify { if ($x -> is_nan()) { require Math::Complex; - my $inf = Math::Complex::Inf(); + my $inf = $Math::Complex::Inf; return $inf - $inf; } if ($x -> is_inf()) { require Math::Complex; - my $inf = Math::Complex::Inf(); + my $inf = $Math::Complex::Inf; return $x -> is_negative() ? -$inf : $inf; } @@ -4105,95 +4227,147 @@ sub import { my $class = shift; $IMPORT++; # remember we did import() my @a; # unrecognized arguments + my @libs; # backend libriaries my $warn_or_die = 0; # 0 - no warn, 1 - warn, 2 - die + for (my $i = 0; $i <= $#_ ; $i++) { + croak "Error in import(): argument with index $i is undefined" + unless defined($_[$i]); + + # Enable overloading of constants. + if ($_[$i] eq ':constant') { - # this causes overlord er load to step in overload::constant integer => sub { $class->new(shift) }, binary => sub { $class->new(shift) }; - } elsif ($_[$i] eq 'upgrade') { - # this causes upgrading - $upgrade = $_[$i+1]; # or undef to disable + } + + # Enable/disable upgrading. + + elsif ($_[$i] eq 'upgrade') { + $upgrade = $_[$i+1]; # undef to disable $i++; - } elsif ($_[$i] =~ /^(lib|try|only)\z/) { - # this causes a different low lib to take care... - $LIB = $_[$i+1] || ''; - # try => 0 (no warn) + } + + # Use a user-specified backend libray. + + elsif ($_[$i] =~ /^(lib|try|only)\z/) { + # try => 0 (no warn if unavailable module) # lib => 1 (warn on fallback) # only => 2 (die on fallback) $warn_or_die = 1 if $_[$i] eq 'lib'; $warn_or_die = 2 if $_[$i] eq 'only'; + + # Get and check the list of libraries. + + my $userlibs = $_[$i+1]; + croak "Library argument for import parameter '$_[$i]' is undefined" + unless defined($userlibs); + $userlibs =~ s/^\s+//; + $userlibs =~ s/\s+$//; + my @userlibs = split /\s*,\s*/, $userlibs; + carp "Argument for import parameter '$_[$i]' contains no libraries" + unless @userlibs; + + for my $lib (@userlibs) { + # Limit to sane characters. Should we warn about invalid + # characters, i.e., invalid module names? + $lib =~ tr/a-zA-Z0-9_://cd; + if (CORE::length $lib) { + $lib = "Math::BigInt::$lib" if $lib !~ /^Math::BigInt::/i; + push @libs, $lib; + next; + } + carp "Specified library name is empty or invalid"; + } + $i++; - } else { + } + + else { push @a, $_[$i]; } } - # any non :constant stuff is handled by our parent, Exporter + + # Any non ':constant' stuff is handled by our parent, Exporter + if (@a > 0) { $class->SUPER::import(@a); # need it for subclasses $class->export_to_level(1, $class, @a); # need it for MBF } - # try to load core math lib - my @c = split /\s*,\s*/, $LIB; - foreach (@c) { - tr/a-zA-Z0-9://cd; # limit to sane characters - } - push @c, \'Calc' # if all fail, try these - if $warn_or_die < 2; # but not for "only" - $LIB = ''; # signal error - foreach my $l (@c) { - # fallback libraries are "marked" as \'string', extract string if nec. - my $lib = $l; - $lib = $$l if ref($l); - - next unless defined($lib) && CORE::length($lib); - $lib = 'Math::BigInt::'.$lib if $lib !~ /^Math::BigInt/i; - $lib =~ s/\.pm$//; - my @parts = split /::/, $lib; # Math::BigInt => Math BigInt - $parts[-1] .= '.pm'; # BigInt => BigInt.pm - require File::Spec; - my $file = File::Spec->catfile(@parts); - eval { require $file; }; - if ($@ eq '') { - $lib->import(); - $LIB = $lib; - if ($warn_or_die > 0 && ref($l)) { - my $msg = "Math::BigInt: couldn't load specified" - . " math lib(s), fallback to $lib"; - carp($msg) if $warn_or_die == 1; - croak($msg) if $warn_or_die == 2; + if (@libs) { + + # Try to load the specified libraries, if any. + + my $numfail = 0; # increment for each lib that fails to load + for (my $i = 0 ; $i <= $#libs ; $i++) { + my $lib = $libs[$i]; + eval "require $lib"; + unless ($@) { + $LIB = $lib; + last; } - last; # found a usable one, break + $numfail++; } - } - if ($LIB eq '') { - if ($warn_or_die == 2) { - croak("Couldn't load specified math lib(s)" . - " and fallback disallowed"); - } else { - croak("Couldn't load any math lib(s), not even fallback to Calc.pm"); + + # All attempts to load a library failed. + + if ($numfail == @libs) { + + # The fallback library is either the most recently loaded library, + # or the default library, if no library has been successfully yet. + + my $FALLBACK_LIB = defined($LIB) ? $LIB : $DEFAULT_LIB; + + # If the user requested a specific list of modules and didn't allow + # a fallback. + + if ($warn_or_die == 2) { + croak "Couldn't load the specified math lib(s) ", + join(", ", map "'$_'", @libs), + ", and fallback to '$FALLBACK_LIB' is disallowed"; + } + + # The user accepts the use of a fallback library, so try to load it. + # Note that it might already have been loaded successfully, but we + # don't know that, and there is minimal overhead in trying to load + # it again. + + eval "require $FALLBACK_LIB"; + if ($@) { + croak "Couldn't load the specified math lib(s) ", + join(", ", map "'$_'", @libs), + ", not even the fallback lib '$FALLBACK_LIB'"; + } + + # The fallback library was successfully loaded, but the user might + # want to know that we are using the fallback. + + if ($warn_or_die == 1) { + carp "Couldn't load the specified math lib(s) ", + join(", ", map "'$_'", @libs), + ", so using fallback lib '$FALLBACK_LIB'"; + } } } - # notify callbacks - foreach my $class (keys %CALLBACKS) { - &{$CALLBACKS{$class}}($LIB); + # We might not have loaded any backend library yet, either because the user + # didn't specify any, or because the specified libraries failed to load and + # the user allows the use of a fallback library. + + unless (defined $LIB) { + eval "require $DEFAULT_LIB"; + if ($@) { + croak "No lib specified, and couldn't load the default", + " lib '$DEFAULT_LIB'"; + } + $LIB = $DEFAULT_LIB; } # import done } -sub _register_callback { - my ($class, $callback) = @_; - - if (ref($callback) ne 'CODE') { - croak("$callback is not a coderef"); - } - $CALLBACKS{$class} = $callback; -} - sub _split_dec_string { my $str = shift; @@ -4448,13 +4622,13 @@ Math::BigInt - Arbitrary size integer/float math package # pure Perl if the GMP library is not installed): # (See also the L<MATH LIBRARY> section!) - # warns if Math::BigInt::GMP cannot be found + # to warn if Math::BigInt::GMP cannot be found, use use Math::BigInt lib => 'GMP'; - # to suppress the warning use this: + # to suppress the warning if Math::BigInt::GMP cannot be found, use # use Math::BigInt try => 'GMP'; - # dies if GMP cannot be loaded: + # to die if Math::BigInt::GMP cannot be found, use # use Math::BigInt only => 'GMP'; my $str = '1234567890'; @@ -4483,6 +4657,7 @@ Math::BigInt - Arbitrary size integer/float math package $x = Math::BigInt->from_oct('377'); # from octal $x = Math::BigInt->from_bin('1101'); # from binary $x = Math::BigInt->from_base('why', 36); # from any base + $x = Math::BigInt->from_base_num([1, 0], 2); # from any base $x = Math::BigInt->bzero(); # create a +0 $x = Math::BigInt->bone(); # create a +1 $x = Math::BigInt->bone('-'); # create a -1 @@ -4559,6 +4734,9 @@ Math::BigInt - Arbitrary size integer/float math package $x->bsqrt(); # calculate square root $x->broot($y); # $y'th root of $x (e.g. $y == 3 => cubic root) $x->bfac(); # factorial of $x (1*2*3*4*..$x) + $x->bdfac(); # double factorial of $x ($x*($x-2)*($x-4)*...) + $x->btfac(); # triple factorial of $x ($x*($x-3)*($x-6)*...) + $x->bmfac($k); # $k'th multi-factorial of $x ($x*($x-$k)*...) $x->blsft($n); # left shift $n places in base 2 $x->blsft($n,$b); # left shift $n places in base $b @@ -4619,6 +4797,7 @@ Math::BigInt - Arbitrary size integer/float math package $x->to_oct(); # as signed octal string $x->to_bytes(); # as byte string $x->to_base($b); # as string in any base + $x->to_base_num($b); # as array of integers in any base $x->as_hex(); # as signed hexadecimal string with prefixed 0x $x->as_bin(); # as signed binary string with prefixed 0b @@ -4646,7 +4825,7 @@ Leading and trailing whitespace is ignored. =item * -Leading and trailing zeros are ignored. +Leading zeros are ignored. =item * @@ -4654,6 +4833,10 @@ If the string has a "0x" prefix, it is interpreted as a hexadecimal number. =item * +If the string has a "0o" prefix, it is interpreted as an octal number. + +=item * + If the string has a "0b" prefix, it is interpreted as a binary number. =item * @@ -4666,10 +4849,6 @@ If the string can not be interpreted, NaN is returned. =back -Octal numbers are typically prefixed by "0", but since leading zeros are -stripped, these methods can not automatically recognize octal numbers, so use -the constructor from_oct() to interpret octal strings. - Some examples of valid string input Input string Resulting value @@ -4677,7 +4856,11 @@ Some examples of valid string input 1.23e2 123 12300e-2 123 0xcafe 51966 + 0XCAFE 51966 + 0o1337 735 + 0O1337 735 0b1101 13 + 0B1101 13 67_538_754 67538754 -4_5_6.7_8_9e+0_1_0 -4567890000000 @@ -4969,6 +5152,16 @@ are equivalent $x = Math::BigInt->from_base("100", 2, "01"); # $x is 4 $x = Math::BigInt->from_base("|--", 2, "-|"); # $x is 4 +=item from_base_num() + +Returns a new Math::BigInt object given an array of values and a base. This +method is equivalent to C<from_base()>, but works on numbers in an array rather +than characters in a string. Unlike C<from_base()>, all input values may be +arbitrarily large. + + $x = Math::BigInt->from_base_num([1, 1, 0, 1], 2) # $x is 13 + $x = Math::BigInt->from_base_num([3, 125, 39], 128) # $x is 65191 + =item bzero() $x = Math::BigInt->bzero(); @@ -5539,19 +5732,35 @@ Calculates the N'th root of C<$x>. =item bfac() - $x->bfac(); # factorial of $x (1*2*3*4*..*$x) + $x->bfac(); # factorial of $x -Returns the factorial of C<$x>, i.e., the product of all positive integers up -to and including C<$x>. +Returns the factorial of C<$x>, i.e., $x*($x-1)*($x-2)*...*2*1, the product of +all positive integers up to and including C<$x>. C<$x> must be > -1. The +factorial of N is commonly written as N!, or N!1, when using the multifactorial +notation. =item bdfac() - $x->bdfac(); # double factorial of $x (1*2*3*4*..*$x) + $x->bdfac(); # double factorial of $x + +Returns the double factorial of C<$x>, i.e., $x*($x-2)*($x-4)*... C<$x> must be +> -2. The double factorial of N is commonly written as N!!, or N!2, when using +the multifactorial notation. + +=item btfac() + + $x->btfac(); # triple factorial of $x + +Returns the triple factorial of C<$x>, i.e., $x*($x-3)*($x-6)*... C<$x> must be +> -3. The triple factorial of N is commonly written as N!!!, or N!3, when using +the multifactorial notation. -Returns the double factorial of C<$x>. If C<$x> is an even integer, returns the -product of all positive, even integers up to and including C<$x>, i.e., -2*4*6*...*$x. If C<$x> is an odd integer, returns the product of all positive, -odd integers, i.e., 1*3*5*...*$x. +=item bmfac() + + $x->bmfac($k); # $k'th multifactorial of $x + +Returns the multi-factorial of C<$x>, i.e., $x*($x-$k)*($x-2*$k)*... C<$x> must +be > -$k. The multi-factorial of N is commonly written as N!K. =item bfib() @@ -5954,6 +6163,19 @@ Here are some more examples See from_base() for information and examples. +=item to_base_num() + +Converts the given number to the given base. This method is equivalent to +C<_to_base()>, but returns numbers in an array rather than characters in a +string. In the output, the first element is the most significant. Unlike +C<_to_base()>, all input values may be arbitrarily large. + + $x = Math::BigInt->new(13); + $x->to_base_num(2); # returns [1, 1, 0, 1] + + $x = Math::BigInt->new(65191); + $x->to_base_num(128); # returns [3, 125, 39] + =item as_hex() $x->as_hex(); @@ -6385,32 +6607,68 @@ instead relying on the internal representation. =head2 MATH LIBRARY -Math with the numbers is done (by default) by a module called -C<Math::BigInt::Calc>. This is equivalent to saying: +The mathematical computations are performed by a backend library. It is not +required to specify which backend library to use, but some backend libraries +are much faster than the default library. + +=head3 The default library + +The default library is L<Math::BigInt::Calc>, which is implemented in +pure Perl and hence does not require a compiler. + +=head3 Specifying a library + +The simple case + + use Math::BigInt; + +is equivalent to saying use Math::BigInt try => 'Calc'; -You can change this backend library by using: +You can use a different backend library with, e.g., use Math::BigInt try => 'GMP'; -B<Note>: General purpose packages should not be explicit about the library to -use; let the script author decide which is best. +which attempts to load the L<Math::BigInt::GMP> library, and falls back to the +default library if the specified library can't be loaded. + +Multiple libraries can be specified by separating them by a comma, e.g., + + use Math::BigInt try => 'GMP,Pari'; -If your script works with huge numbers and Calc is too slow for them, you can -also for the loading of one of these libraries and if none of them can be used, -the code dies: +If you request a specific set of libraries and do not allow fallback, specify +them using "only", use Math::BigInt only => 'GMP,Pari'; -The following would first try to find Math::BigInt::Foo, then -Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc: +If you prefer a specific set of libraries, but want to see a warning if the +fallback library is used, specify them using "lib", + + use Math::BigInt lib => 'GMP,Pari'; + +The following first tries to find Math::BigInt::Foo, then Math::BigInt::Bar, and +if this also fails, reverts to Math::BigInt::Calc: use Math::BigInt try => 'Foo,Math::BigInt::Bar'; -The library that is loaded last is used. Note that this can be overwritten at -any time by loading a different library, and numbers constructed with different -libraries cannot be used in math operations together. +=head3 The fallback library + +The library that is used is the first library that was successfully loaded. The +fallback library is the most recent library that was successfully loaded, or the +default library, if no library has been successfully loaded. + +In the following example, assume "Pari" can be loaded, but "Foo" can't. Since +"Pari" can be loaded, it is used. Since "Foo" can't be loaded, "Pari" is used as +the fallback library, since it is the most recently successfully loaded library. + + use Math::BigInt; # "Calc" (default) is used + use Math::BigInt try => "Pari"; # "Pari" is used + use Math::BigFloat try => "Foo"; # fallback to "Pari" + +As shown, multiple libraries can be loaded, and the library in used can be +changed. However, all library loading should be done before any objects are +created. Mixing objects that use different backend libraries won't work. =head3 What library to use? @@ -6418,16 +6676,16 @@ B<Note>: General purpose packages should not be explicit about the library to use; let the script author decide which is best. L<Math::BigInt::GMP> and L<Math::BigInt::Pari> are in cases involving big -numbers much faster than Calc, however it is slower when dealing with very -small numbers (less than about 20 digits) and when converting very large -numbers to decimal (for instance for printing, rounding, calculating their -length in decimal etc). +numbers much faster than L<Math::BigInt::Calc>. However it is slower when +dealing with very small numbers (less than about 20 digits) and when converting +very large numbers to decimal (for instance for printing, rounding, calculating +their length in decimal etc.). So please select carefully what library you want to use. -Different low-level libraries use different formats to store the numbers. -However, you should B<NOT> depend on the number having a specific format -internally. +Different low-level libraries use different formats to store the numbers, so +mixing them won't work. You should not depend on the number having a specific +internal format. See the respective math library module documentation for further details. @@ -6871,17 +7129,13 @@ You can also look for information at: =over 4 -=item * RT: CPAN's request tracker +=item * GitHub -L<https://rt.cpan.org/Public/Dist/Display.html?Name=Math-BigInt> +L<https://github.com/pjacklam/p5-Math-BigInt> -=item * AnnoCPAN: Annotated CPAN documentation - -L<http://annocpan.org/dist/Math-BigInt> - -=item * CPAN Ratings +=item * RT: CPAN's request tracker -L<https://cpanratings.perl.org/dist/Math-BigInt> +L<https://rt.cpan.org/Dist/Display.html?Name=Math-BigInt> =item * MetaCPAN @@ -6891,6 +7145,10 @@ L<https://metacpan.org/release/Math-BigInt> L<http://matrix.cpantesters.org/?dist=Math-BigInt> +=item * CPAN Ratings + +L<https://cpanratings.perl.org/dist/Math-BigInt> + =item * The Bignum mailing list =over 4 @@ -6942,7 +7200,7 @@ Florian Ragwitz E<lt>flora@cpan.orgE<gt>, 2010. =item * -Peter John Acklam E<lt>pjacklam@online.noE<gt>, 2011-. +Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2011-. =back diff --git a/cpan/Math-BigInt/lib/Math/BigInt/Calc.pm b/cpan/Math-BigInt/lib/Math/BigInt/Calc.pm index cd8f1ee44e..61a5f63acd 100644 --- a/cpan/Math-BigInt/lib/Math/BigInt/Calc.pm +++ b/cpan/Math-BigInt/lib/Math/BigInt/Calc.pm @@ -7,89 +7,169 @@ use warnings; use Carp qw< carp croak >; use Math::BigInt::Lib; -our $VERSION = '1.999818'; +our $VERSION = '1.999823'; our @ISA = ('Math::BigInt::Lib'); # Package to store unsigned big integers in decimal and do math with them - +# # Internally the numbers are stored in an array with at least 1 element, no # leading zero parts (except the first) and in base 1eX where X is determined # automatically at loading time to be the maximum possible value - +# # todo: # - fully remove funky $# stuff in div() (maybe - that code scares me...) -# USE_MUL: due to problems on certain os (os390, posix-bc) "* 1e-5" is used -# instead of "/ 1e5" at some places, (marked with USE_MUL). Other platforms -# BS2000, some Crays need USE_DIV instead. -# The BEGIN block is used to determine which of the two variants gives the -# correct result. - -# Beware of things like: -# $i = $i * $y + $car; $car = int($i / $BASE); $i = $i % $BASE; -# This works on x86, but fails on ARM (SA1100, iPAQ) due to who knows what -# reasons. So, use this instead (slower, but correct): -# $i = $i * $y + $car; $car = int($i / $BASE); $i -= $BASE * $car; - ############################################################################## # global constants, flags and accessory # constants for easier life -my ($BASE, $BASE_LEN, $RBASE, $MAX_VAL); -my ($AND_BITS, $XOR_BITS, $OR_BITS); -my ($AND_MASK, $XOR_MASK, $OR_MASK); -sub _base_len { - # Set/get the BASE_LEN and assorted other, related values. - # Used only by the testsuite, the set variant is used only by the BEGIN - # block below: - - my ($class, $b, $int) = @_; - if (defined $b) { - no warnings "redefine"; - - if ($] >= 5.008 && $int && $b > 7) { - $BASE_LEN = $b; - *_mul = \&_mul_use_div_64; - *_div = \&_div_use_div_64; - $BASE = int("1e" . $BASE_LEN); - $MAX_VAL = $BASE-1; - return $BASE_LEN unless wantarray; - return ($BASE_LEN, $BASE, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN, $MAX_VAL); - } +my $MAX_EXP_F; # the maximum possible base 10 exponent with "no integer" +my $MAX_EXP_I; # the maximum possible base 10 exponent with "use integer" + +my $MAX_BITS; # the maximum possible number of bits for $AND_BITS etc. + +my $BASE_LEN; # the current base exponent in use +my $USE_INT; # whether "use integer" is used in the computations + +my $BASE; # the current base, e.g., 10000 if $BASE_LEN is 5 +my $MAX_VAL; # maximum value for an element, i.e., $BASE - 1 + +my $AND_BITS; # maximum value used in binary and, e.g., 0xffff +my $OR_BITS; # ditto for binary or +my $XOR_BITS; # ditto for binary xor + +my $AND_MASK; # $AND_BITS + 1, e.g., 0x10000 if $AND_BITS is 0xffff +my $OR_MASK; # ditto for binary or +my $XOR_MASK; # ditto for binary xor + +sub config { + my $self = shift; - # find whether we can use mul or div in mul()/div() - $BASE_LEN = $b + 1; - my $caught = 0; - while (--$BASE_LEN > 5) { - $BASE = int("1e" . $BASE_LEN); - $RBASE = abs('1e-' . $BASE_LEN); # see USE_MUL - $caught = 0; - $caught += 1 if (int($BASE * $RBASE) != 1); # should be 1 - $caught += 2 if (int($BASE / $BASE) != 1); # should be 1 - last if $caught != 3; + croak "Missing input argument" unless @_; + + # Called as a getter. + + if (@_ == 1) { + my $param = shift; + croak "Parameter name must be a non-empty string" + unless defined $param && length $param; + return $BASE_LEN if $param eq 'base_len'; + return $USE_INT if $param eq 'use_int'; + croak "Unknown parameter '$param'"; + } + + # Called as a setter. + + my $opts; + while (@_) { + my $param = shift; + croak "Parameter name must be a non-empty string" + unless defined $param && length $param; + croak "Missing value for parameter '$param'" + unless @_; + my $value = shift; + + if ($param eq 'base_len' || $param eq 'use_int') { + $opts -> {$param} = $value; + next; } - $BASE = int("1e" . $BASE_LEN); - $RBASE = abs('1e-' . $BASE_LEN); # see USE_MUL - $MAX_VAL = $BASE-1; - # ($caught & 1) != 0 => cannot use MUL - # ($caught & 2) != 0 => cannot use DIV - if ($caught == 2) # 2 + croak "Unknown parameter '$param'"; + } + + $BASE_LEN = $opts -> {base_len} if exists $opts -> {base_len}; + $USE_INT = $opts -> {use_int} if exists $opts -> {use_int}; + __PACKAGE__ -> _base_len($BASE_LEN, $USE_INT); + + return $self; +} + +sub _base_len { + my $class = shift; + + if (@_) { # if called as setter ... + my ($base_len, $use_int) = @_; + + croak "The base length must be a positive integer" + unless defined($base_len) && $base_len == int($base_len) + && $base_len > 0; + + if ( $use_int && ($base_len > $MAX_EXP_I) || + !$use_int && ($base_len > $MAX_EXP_F)) { - # must USE_MUL since we cannot use DIV - *_mul = \&_mul_use_mul; - *_div = \&_div_use_mul; - } else # 0 or 1 + croak "The maximum base length (exponent) is $MAX_EXP_I with", + " 'use integer' and $MAX_EXP_F without 'use integer'. The", + " requested settings, a base length of $base_len ", + $use_int ? "with" : "without", " 'use integer', is invalid."; + } + + $BASE_LEN = $base_len; + $BASE = 0 + ("1" . ("0" x $BASE_LEN)); + $MAX_VAL = $BASE - 1; + $USE_INT = $use_int ? 1 : 0; + { - # can USE_DIV instead - *_mul = \&_mul_use_div; - *_div = \&_div_use_div; + no warnings "redefine"; + if ($use_int) { + *_mul = \&_mul_use_int; + *_div = \&_div_use_int; + } else { + *_mul = \&_mul_no_int; + *_div = \&_div_no_int; + } } } + + # Find max bits. This is the largest power of two that is both no larger + # than $BASE and no larger than the maximum integer (i.e., ~0). We need + # this limitation because _and(), _or(), and _xor() only work on one + # element at a time. + + my $umax = ~0; # largest unsigned integer + my $tmp = $umax < $BASE ? $umax : $BASE; + + $MAX_BITS = 0; + while ($tmp >>= 1) { + $MAX_BITS++; + } + + # Limit to 32 bits for portability. Is this really necessary? XXX + + $MAX_BITS = 32 if $MAX_BITS > 32; + + # Find out how many bits _and, _or and _xor can take (old default = 16). + # Are these tests really necessary? Can't we just use $MAX_BITS? XXX + + for ($AND_BITS = $MAX_BITS ; $AND_BITS > 0 ; $AND_BITS--) { + my $x = CORE::oct('0b' . '1' x $AND_BITS); + my $y = $x & $x; + my $z = 2 * (2 ** ($AND_BITS - 1)) + 1; + last unless $AND_BITS < $MAX_BITS && $x == $z && $y == $x; + } + + for ($XOR_BITS = $MAX_BITS ; $XOR_BITS > 0 ; $XOR_BITS--) { + my $x = CORE::oct('0b' . '1' x $XOR_BITS); + my $y = $x ^ $x; + my $z = 2 * (2 ** ($XOR_BITS - 1)) + 1; + last unless $XOR_BITS < $MAX_BITS && $x == $z && $y == $x; + } + + for ($OR_BITS = $MAX_BITS ; $OR_BITS > 0 ; $OR_BITS--) { + my $x = CORE::oct('0b' . '1' x $OR_BITS); + my $y = $x | $x; + my $z = 2 * (2 ** ($OR_BITS - 1)) + 1; + last unless $OR_BITS < $MAX_BITS && $x == $z && $y == $x; + } + + $AND_MASK = __PACKAGE__->_new(( 2 ** $AND_BITS )); + $XOR_MASK = __PACKAGE__->_new(( 2 ** $XOR_BITS )); + $OR_MASK = __PACKAGE__->_new(( 2 ** $OR_BITS )); + return $BASE_LEN unless wantarray; - return ($BASE_LEN, $BASE, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN, $MAX_VAL); + return ($BASE_LEN, $BASE, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN, $MAX_VAL, + $MAX_BITS, $MAX_EXP_F, $MAX_EXP_I, $USE_INT); } sub _new { @@ -116,89 +196,65 @@ sub _new { } BEGIN { - # from Daniel Pfeiffer: determine largest group of digits that is precisely - # multipliable with itself plus carry - # Test now changed to expect the proper pattern, not a result off by 1 or 2 - my ($e, $num) = 3; # lowest value we will use is 3+1-1 = 3 - do { - $num = '9' x ++$e; - $num *= $num + 1; - } while $num =~ /9{$e}0{$e}/; # must be a certain pattern - $e--; # last test failed, so retract one step - # the limits below brush the problems with the test above under the rug: - # the test should be able to find the proper $e automatically - $e = 5 if $^O =~ /^uts/; # UTS get's some special treatment - $e = 5 if $^O =~ /^unicos/; # unicos is also problematic (6 seems to work - # there, but we play safe) - - my $int = 0; - if ($e > 7) { - use integer; - my $e1 = 7; - $num = 7; - do { - $num = ('9' x ++$e1) + 0; - $num *= $num + 1; - } while ("$num" =~ /9{$e1}0{$e1}/); # must be a certain pattern - $e1--; # last test failed, so retract one step - if ($e1 > 7) { - $int = 1; - $e = $e1; - } - } - __PACKAGE__ -> _base_len($e, $int); # set and store + # Compute $MAX_EXP_F, the maximum usable base 10 exponent. - use integer; - # find out how many bits _and, _or and _xor can take (old default = 16) - # I don't think anybody has yet 128 bit scalars, so let's play safe. - local $^W = 0; # don't warn about 'nonportable number' - $AND_BITS = 15; - $XOR_BITS = 15; - $OR_BITS = 15; - - # find max bits, we will not go higher than numberofbits that fit into $BASE - # to make _and etc simpler (and faster for smaller, slower for large numbers) - my $max = 16; - while (2 ** $max < $BASE) { - $max++; + # The largest element in base 10**$BASE_LEN is 10**$BASE_LEN-1. For instance, + # with $BASE_LEN = 5, the largest element is 99_999, and the largest carry is + # + # int( 99_999 * 99_999 / 100_000 ) = 99_998 + # + # so make sure that 99_999 * 99_999 + 99_998 is within the range of integers + # that can be represented accuratly. + # + # Note that on some systems with quadmath support, the following is within + # the range of numbers that can be represented exactly, but it still gives + # the incorrect value $r = 2 (even though POSIX::fmod($x, $y) gives the + # correct value of 1: + # + # $x = 99999999999999999; + # $y = 100000000000000000; + # $r = $x * $x % $y; # should be 1 + # + # so also check for this. + + for ($MAX_EXP_F = 1 ; ; $MAX_EXP_F++) { # when $MAX_EXP_F = 5 + my $MAX_EXP_FM1 = $MAX_EXP_F - 1; # = 4 + my $bs = "1" . ("0" x $MAX_EXP_F); # = "100000" + my $xs = "9" x $MAX_EXP_F; # = "99999" + my $cs = ("9" x $MAX_EXP_FM1) . "8"; # = "99998" + my $ys = $cs . ("0" x $MAX_EXP_FM1) . "1"; # = "9999800001" + + # Compute and check the product. + my $yn = $xs * $xs; # = 9999800001 + last if $yn != $ys; + + # Compute and check the remainder. + my $rn = $yn % $bs; # = 1 + last if $rn != 1; + + # Compute and check the carry. The division here is exact. + my $cn = ($yn - $rn) / $bs; # = 99998 + last if $cn != $cs; + + # Compute and check product plus carry. + my $zs = $cs . ("9" x $MAX_EXP_F); # = "9999899999" + my $zn = $yn + $cn; # = 99998999999 + last if $zn != $zs; + last if $zn - ($zn - 1) != 1; } - { - no integer; - $max = 16 if $] < 5.006; # older Perls might not take >16 too well - } - my ($x, $y, $z); - - do { - $AND_BITS++; - $x = CORE::oct('0b' . '1' x $AND_BITS); - $y = $x & $x; - $z = (2 ** $AND_BITS) - 1; - } while ($AND_BITS < $max && $x == $z && $y == $x); - $AND_BITS --; # retreat one step - - do { - $XOR_BITS++; - $x = CORE::oct('0b' . '1' x $XOR_BITS); - $y = $x ^ 0; - $z = (2 ** $XOR_BITS) - 1; - } while ($XOR_BITS < $max && $x == $z && $y == $x); - $XOR_BITS --; # retreat one step - - do { - $OR_BITS++; - $x = CORE::oct('0b' . '1' x $OR_BITS); - $y = $x | $x; - $z = (2 ** $OR_BITS) - 1; - } while ($OR_BITS < $max && $x == $z && $y == $x); - $OR_BITS--; # retreat one step + $MAX_EXP_F--; # last test failed, so retract one step - $AND_MASK = __PACKAGE__->_new(( 2 ** $AND_BITS )); - $XOR_MASK = __PACKAGE__->_new(( 2 ** $XOR_BITS )); - $OR_MASK = __PACKAGE__->_new(( 2 ** $OR_BITS )); + # Compute $MAX_EXP_I, the maximum usable base 10 exponent within the range + # of what is available with "use integer". - # We can compute the approximate length no faster than the real length: - *_alen = \&_len; + my $umax = ~0; # largest unsigned integer + $MAX_EXP_I = int(0.5 * log($umax) / log(10)); + + ($BASE_LEN, $USE_INT) = $MAX_EXP_F > $MAX_EXP_I + ? ($MAX_EXP_F, 0) : ($MAX_EXP_I, 1); + + __PACKAGE__ -> _base_len($BASE_LEN, $USE_INT); } ############################################################################### @@ -224,18 +280,20 @@ sub _two { sub _ten { # create a 10 my $class = shift; - bless [ 10 ], $class; + my $self = $BASE_LEN == 1 ? [ 0, 1 ] : [ 10 ]; + bless $self, $class; } sub _1ex { # create a 1Ex my $class = shift; - my $rem = $_[0] % $BASE_LEN; # remainder - my $parts = $_[0] / $BASE_LEN; # parts + my $rem = $_[0] % $BASE_LEN; # remainder + my $div = ($_[0] - $rem) / $BASE_LEN; # parts - # 000000, 000000, 100 - bless [ (0) x $parts, '1' . ('0' x $rem) ], $class; + # With a $BASE_LEN of 6, 1e14 becomes + # [ 000000, 000000, 100 ] -> [ 0, 0, 100 ] + bless [ (0) x $div, 0 + ("1" . ("0" x $rem)) ], $class; } sub _copy { @@ -244,8 +302,33 @@ sub _copy { return bless [ @{ $_[0] } ], $class; } -# catch and throw away -sub import { } +sub import { + my $self = shift; + + my $opts; + my ($base_len, $use_int); + while (@_) { + my $param = shift; + croak "Parameter name must be a non-empty string" + unless defined $param && length $param; + croak "Missing value for parameter '$param'" + unless @_; + my $value = shift; + + if ($param eq 'base_len' || $param eq 'use_int') { + $opts -> {$param} = $value; + next; + } + + croak "Unknown parameter '$param'"; + } + + $base_len = exists $opts -> {base_len} ? $opts -> {base_len} : $BASE_LEN; + $use_int = exists $opts -> {use_int} ? $opts -> {use_int} : $USE_INT; + __PACKAGE__ -> _base_len($base_len, $use_int); + + return $self; +} ############################################################################## # convert back to string and number @@ -391,76 +474,12 @@ sub _sub { __strip_zeros($sy); } -sub _mul_use_mul { - # (ref to int_num_array, ref to int_num_array) - # multiply two numbers in internal representation - # modifies first arg, second need not be different from first - my ($c, $xv, $yv) = @_; - - if (@$yv == 1) { - # shortcut for two very short numbers (improved by Nathan Zook) works - # also if xv and yv are the same reference, and handles also $x == 0 - if (@$xv == 1) { - if (($xv->[0] *= $yv->[0]) >= $BASE) { - my $rem = $xv->[0] % $BASE; - $xv->[1] = ($xv->[0] - $rem) * $RBASE; - $xv->[0] = $rem; - } - return $xv; - } - # $x * 0 => 0 - if ($yv->[0] == 0) { - @$xv = (0); - return $xv; - } - - # multiply a large number a by a single element one, so speed up - my $y = $yv->[0]; - my $car = 0; - my $rem; - foreach my $i (@$xv) { - $i = $i * $y + $car; - $rem = $i % $BASE; - $car = ($i - $rem) * $RBASE; - $i = $rem; - } - push @$xv, $car if $car != 0; - return $xv; - } - - # shortcut for result $x == 0 => result = 0 - return $xv if @$xv == 1 && $xv->[0] == 0; - - # since multiplying $x with $x fails, make copy in this case - $yv = $c->_copy($xv) if $xv == $yv; # same references? - - my @prod = (); - my ($prod, $rem, $car, $cty, $xi, $yi); - for $xi (@$xv) { - $car = 0; - $cty = 0; - # looping through this if $xi == 0 is silly - so optimize it away! - $xi = (shift(@prod) || 0), next if $xi == 0; - for $yi (@$yv) { - $prod = $xi * $yi + ($prod[$cty] || 0) + $car; - $rem = $prod % $BASE; - $car = int(($prod - $rem) * $RBASE); - $prod[$cty++] = $rem; - } - $prod[$cty] += $car if $car; # need really to check for 0? - $xi = shift(@prod) || 0; # || 0 makes v5.005_3 happy - } - push @$xv, @prod; - $xv; -} - -sub _mul_use_div_64 { +sub _mul_use_int { # (ref to int_num_array, ref to int_num_array) # multiply two numbers in internal representation # modifies first arg, second need not be different from first # works for 64 bit integer with "use integer" my ($c, $xv, $yv) = @_; - use integer; if (@$yv == 1) { @@ -515,7 +534,7 @@ sub _mul_use_div_64 { $xv; } -sub _mul_use_div { +sub _mul_no_int { # (ref to int_num_array, ref to int_num_array) # multiply two numbers in internal representation # modifies first arg, second need not be different from first @@ -578,166 +597,7 @@ sub _mul_use_div { $xv; } -sub _div_use_mul { - # ref to array, ref to array, modify first array and return remainder if - # in list context - - my ($c, $x, $yorg) = @_; - - # the general div algorithm here is about O(N*N) and thus quite slow, so - # we first check for some special cases and use shortcuts to handle them. - - # if both numbers have only one element: - if (@$x == 1 && @$yorg == 1) { - # shortcut, $yorg and $x are two small numbers - my $rem = [ $x->[0] % $yorg->[0] ]; - bless $rem, $c; - $x->[0] = ($x->[0] - $rem->[0]) / $yorg->[0]; - return ($x, $rem) if wantarray; - return $x; - } - - # if x has more than one, but y has only one element: - if (@$yorg == 1) { - my $rem; - $rem = $c->_mod($c->_copy($x), $yorg) if wantarray; - - # shortcut, $y is < $BASE - my $j = @$x; - my $r = 0; - my $y = $yorg->[0]; - my $b; - while ($j-- > 0) { - $b = $r * $BASE + $x->[$j]; - $r = $b % $y; - $x->[$j] = ($b - $r) / $y; - } - pop(@$x) if @$x > 1 && $x->[-1] == 0; # remove any trailing zero - return ($x, $rem) if wantarray; - return $x; - } - - # now x and y have more than one element - - # check whether y has more elements than x, if so, the result is 0 - if (@$yorg > @$x) { - my $rem; - $rem = $c->_copy($x) if wantarray; # make copy - @$x = 0; # set to 0 - return ($x, $rem) if wantarray; # including remainder? - return $x; # only x, which is [0] now - } - - # check whether the numbers have the same number of elements, in that case - # the result will fit into one element and can be computed efficiently - if (@$yorg == @$x) { - my $cmp = 0; - for (my $j = $#$x ; $j >= 0 ; --$j) { - last if $cmp = $x->[$j] - $yorg->[$j]; - } - - if ($cmp == 0) { # x = y - @$x = 1; - return $x, $c->_zero() if wantarray; - return $x; - } - - if ($cmp < 0) { # x < y - if (wantarray) { - my $rem = $c->_copy($x); - @$x = 0; - return $x, $rem; - } - @$x = 0; - return $x; - } - } - - # all other cases: - - my $y = $c->_copy($yorg); # always make copy to preserve - - my $tmp = $y->[-1] + 1; - my $rem = $BASE % $tmp; - my $dd = ($BASE - $rem) / $tmp; - if ($dd != 1) { - my $car = 0; - for my $xi (@$x) { - $xi = $xi * $dd + $car; - $xi -= ($car = int($xi * $RBASE)) * $BASE; # see USE_MUL - } - push(@$x, $car); - $car = 0; - for my $yi (@$y) { - $yi = $yi * $dd + $car; - $yi -= ($car = int($yi * $RBASE)) * $BASE; # see USE_MUL - } - } else { - push(@$x, 0); - } - - # @q will accumulate the final result, $q contains the current computed - # part of the final result - - my @q = (); - my ($v2, $v1) = @$y[-2, -1]; - $v2 = 0 unless $v2; - while ($#$x > $#$y) { - my ($u2, $u1, $u0) = @$x[-3 .. -1]; - $u2 = 0 unless $u2; - #warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n" - # if $v1 == 0; - my $tmp = $u0 * $BASE + $u1; - my $rem = $tmp % $v1; - my $q = $u0 == $v1 ? $MAX_VAL : (($tmp - $rem) / $v1); - --$q while $v2 * $q > ($u0 * $BASE + $u1 - $q * $v1) * $BASE + $u2; - if ($q) { - my $prd; - my ($car, $bar) = (0, 0); - for (my $yi = 0, my $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) { - $prd = $q * $y->[$yi] + $car; - $prd -= ($car = int($prd * $RBASE)) * $BASE; # see USE_MUL - $x->[$xi] += $BASE if $bar = (($x->[$xi] -= $prd + $bar) < 0); - } - if ($x->[-1] < $car + $bar) { - $car = 0; - --$q; - for (my $yi = 0, my $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) { - $x->[$xi] -= $BASE - if $car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE); - } - } - } - pop(@$x); - unshift(@q, $q); - } - - if (wantarray) { - my $d = bless [], $c; - if ($dd != 1) { - my $car = 0; - my ($prd, $rem); - for my $xi (reverse @$x) { - $prd = $car * $BASE + $xi; - $rem = $prd % $dd; - $tmp = ($prd - $rem) / $dd; - $car = $rem; - unshift @$d, $tmp; - } - } else { - @$d = @$x; - } - @$x = @q; - __strip_zeros($x); - __strip_zeros($d); - return ($x, $d); - } - @$x = @q; - __strip_zeros($x); - $x; -} - -sub _div_use_div_64 { +sub _div_use_int { # ref to array, ref to array, modify first array and return remainder if # in list context @@ -900,7 +760,7 @@ sub _div_use_div_64 { $x; } -sub _div_use_div { +sub _div_no_int { # ref to array, ref to array, modify first array and return remainder if # in list context @@ -1157,12 +1017,12 @@ sub _is_zero { sub _is_even { # return true if arg is even - $_[1]->[0] & 1 ? 0 : 1; + $_[1]->[0] % 2 ? 0 : 1; } sub _is_odd { # return true if arg is odd - $_[1]->[0] & 1 ? 1 : 0; + $_[1]->[0] % 2 ? 1 : 0; } sub _is_one { @@ -1177,7 +1037,11 @@ sub _is_two { sub _is_ten { # return true if arg is ten - @{$_[1]} == 1 && $_[1]->[0] == 10 ? 1 : 0; + if ($BASE_LEN == 1) { + @{$_[1]} == 2 && $_[1]->[0] == 0 && $_[1]->[1] == 1 ? 1 : 0; + } else { + @{$_[1]} == 1 && $_[1]->[0] == 10 ? 1 : 0; + } } sub __strip_zeros { @@ -1316,17 +1180,21 @@ sub _mod { # shifts sub _rsft { - my ($c, $x, $y, $n) = @_; + my ($c, $x, $n, $b) = @_; + return $x if $c->_is_zero($x) || $c->_is_zero($n); + + # For backwards compatibility, allow the base $b to be a scalar. - if ($n != 10) { - $n = $c->_new($n); - return scalar $c->_div($x, $c->_pow($n, $y)); + $b = $c->_new($b) unless ref $b; + + if ($c -> _acmp($b, $c -> _ten())) { + return scalar $c->_div($x, $c->_pow($c->_copy($b), $n)); } # shortcut (faster) for shifting by 10) # multiples of $BASE_LEN my $dst = 0; # destination - my $src = $c->_num($y); # as normal int + my $src = $c->_num($n); # as normal int my $xlen = (@$x - 1) * $BASE_LEN + length(int($x->[-1])); if ($src >= $xlen or ($src == $xlen and !defined $x->[1])) { # 12345 67890 shifted right by more than 10 digits => 0 @@ -1519,27 +1387,50 @@ sub _nok { return $n; } -my @factorials = ( - 1, - 1, - 2, - 2*3, - 2*3*4, - 2*3*4*5, - 2*3*4*5*6, - 2*3*4*5*6*7, - ); - sub _fac { # factorial of $x # ref to array, return ref to array my ($c, $cx) = @_; - if ((@$cx == 1) && ($cx->[0] <= 7)) { - $cx->[0] = $factorials[$cx->[0]]; # 0 => 1, 1 => 1, 2 => 2 etc. + # We cache the smallest values. Don't assume that a single element has a + # value larger than 9 or else it won't work with a $BASE_LEN of 1. + + if (@$cx == 1) { + my @factorials = + ( + '1', + '1', + '2', + '6', + '24', + '120', + '720', + '5040', + '40320', + '362880', + ); + if ($cx->[0] <= $#factorials) { + my $tmp = $c -> _new($factorials[ $cx->[0] ]); + @$cx = @$tmp; + return $cx; + } + } + + # The old code further below doesn't work for small values of $BASE_LEN. + # Alas, I have not been able to (or taken the time to) decipher it, so for + # the case when $BASE_LEN is small, we call the parent class. This code + # works in for every value of $x and $BASE_LEN. We could use this code for + # all cases, but it is a little slower than the code further below, so at + # least for now we keep the code below. + + if ($BASE_LEN <= 2) { + my $tmp = $c -> SUPER::_fac($cx); + @$cx = @$tmp; return $cx; } + # This code does not work for small values of $BASE_LEN. + if ((@$cx == 1) && # we do this only if $x >= 12 and $x <= 7000 ($cx->[0] >= 12 && $cx->[0] < 7000)) { @@ -1759,9 +1650,9 @@ sub _log_int { $log += (@$base - 1) * $BASE_LEN; # calculate now a guess based on the values obtained above: - my $res = int($len / $log); + my $res = $c->_new(int($len / $log)); - @$x = $res; + @$x = @$res; my $trial = $c->_pow($c->_copy($base), $x); my $acmp = $c->_acmp($trial, $x_org); @@ -1795,9 +1686,8 @@ my $steps = 0; sub steps { $steps }; sub _sqrt { - # square-root of $x in place - # Compute a guess of the result (by rule of thumb), then improve it via - # Newton's method. + # square-root of $x in-place + my ($c, $x) = @_; if (@$x == 1) { @@ -1805,68 +1695,65 @@ sub _sqrt { $x->[0] = int(sqrt($x->[0])); return $x; } - my $y = $c->_copy($x); - # hopefully _len/2 is < $BASE, the -1 is to always undershot the guess - # since our guess will "grow" - my $l = int(($c->_len($x)-1) / 2); - - my $lastelem = $x->[-1]; # for guess - my $elems = @$x - 1; - # not enough digits, but could have more? - if ((length($lastelem) <= 3) && ($elems > 1)) { - # right-align with zero pad - my $len = length($lastelem) & 1; - print "$lastelem => " if DEBUG; - $lastelem .= substr($x->[-2] . '0' x $BASE_LEN, 0, $BASE_LEN); - # former odd => make odd again, or former even to even again - $lastelem = $lastelem / 10 if (length($lastelem) & 1) != $len; - print "$lastelem\n" if DEBUG; - } - - # construct $x (instead of $c->_lsft($x, $l, 10) - my $r = $l % $BASE_LEN; # 10000 00000 00000 00000 ($BASE_LEN=5) - $l = int($l / $BASE_LEN); - print "l = $l " if DEBUG; - - splice @$x, $l; # keep ref($x), but modify it - - # we make the first part of the guess not '1000...0' but int(sqrt($lastelem)) - # that gives us: - # 14400 00000 => sqrt(14400) => guess first digits to be 120 - # 144000 000000 => sqrt(144000) => guess 379 - - print "$lastelem (elems $elems) => " if DEBUG; - $lastelem = $lastelem / 10 if ($elems & 1 == 1); # odd or even? - my $g = sqrt($lastelem); - $g =~ s/\.//; # 2.345 => 2345 - $r -= 1 if $elems & 1 == 0; # 70 => 7 - - # padd with zeros if result is too short - $x->[$l--] = int(substr($g . '0' x $r, 0, $r+1)); - print "now ", $x->[-1] if DEBUG; - print " would have been ", int('1' . '0' x $r), "\n" if DEBUG; - - # If @$x > 1, we could compute the second elem of the guess, too, to create - # an even better guess. Not implemented yet. Does it improve performance? - $x->[$l--] = 0 while ($l >= 0); # all other digits of guess are zero - - print "start x= ", $c->_str($x), "\n" if DEBUG; - my $two = $c->_two(); - my $last = $c->_zero(); - my $lastlast = $c->_zero(); - $steps = 0 if DEBUG; - while ($c->_acmp($last, $x) != 0 && $c->_acmp($lastlast, $x) != 0) { - $steps++ if DEBUG; - $lastlast = $c->_copy($last); - $last = $c->_copy($x); - $c->_add($x, $c->_div($c->_copy($y), $x)); - $c->_div($x, $two ); - print " x= ", $c->_str($x), "\n" if DEBUG; - } - print "\nsteps in sqrt: $steps, " if DEBUG; - $c->_dec($x) if $c->_acmp($y, $c->_mul($c->_copy($x), $x)) < 0; # overshot? - print " final ", $x->[-1], "\n" if DEBUG; - $x; + + # Create an initial guess for the square root. + + my $s; + if (@$x % 2) { + $s = [ (0) x ((@$x - 1) / 2), int(sqrt($x->[-1])) ]; + } else { + $s = [ (0) x ((@$x - 2) / 2), int(sqrt($x->[-2] + $x->[-1] * $BASE)) ]; + } + + # Newton's method for the square root of y: + # + # x(n) * x(n) - y + # x(n+1) = x(n) - ----------------- + # 2 * x(n) + + my $cmp; + while (1) { + my $sq = $c -> _mul($c -> _copy($s), $s); + $cmp = $c -> _acmp($sq, $x); + + # If x(n)*x(n) > y, compute + # + # x(n) * x(n) - y + # x(n+1) = x(n) - ----------------- + # 2 * x(n) + + if ($cmp > 0) { + my $num = $c -> _sub($c -> _copy($sq), $x); + my $den = $c -> _mul($c -> _two(), $s); + my $delta = $c -> _div($num, $den); + last if $c -> _is_zero($delta); + $s = $c -> _sub($s, $delta); + } + + # If x(n)*x(n) < y, compute + # + # y - x(n) * x(n) + # x(n+1) = x(n) + ----------------- + # 2 * x(n) + + elsif ($cmp < 0) { + my $num = $c -> _sub($c -> _copy($x), $sq); + my $den = $c -> _mul($c -> _two(), $s); + my $delta = $c -> _div($num, $den); + last if $c -> _is_zero($delta); + $s = $c -> _add($s, $delta); + } + + # If x(n)*x(n) = y, we have the exact result. + + else { + last; + } + } + + $s = $c -> _dec($s) if $cmp > 0; # never overshoot + @$x = @$s; + return $x; } sub _root { @@ -1876,14 +1763,18 @@ sub _root { # Small numbers. - if (@$x == 1 && @$n == 1) { - # Result can be computed directly. Adjust initial result for numerical - # errors, e.g., int(1000**(1/3)) is 2, not 3. - my $y = int($x->[0] ** (1 / $n->[0])); - my $yp1 = $y + 1; - $y = $yp1 if $yp1 ** $n->[0] == $x->[0]; - $x->[0] = $y; - return $x; + if (@$x == 1) { + return $x if $x -> [0] == 0 || $x -> [0] == 1; + + if (@$n == 1) { + # Result can be computed directly. Adjust initial result for + # numerical errors, e.g., int(1000**(1/3)) is 2, not 3. + my $y = int($x->[0] ** (1 / $n->[0])); + my $yp1 = $y + 1; + $y = $yp1 if $yp1 ** $n->[0] == $x->[0]; + $x->[0] = $y; + return $x; + } } # If x <= n, the result is always (truncated to) 1. @@ -1891,7 +1782,7 @@ sub _root { if ((@$x > 1 || $x -> [0] > 0) && # if x is non-zero ... $c -> _acmp($x, $n) <= 0) # ... and x <= n { - my $one = $x -> _one(); + my $one = $c -> _one(); @$x = @$one; return $x; } @@ -2173,7 +2064,6 @@ sub _or { # $b = 1; $xrr = 0; foreach (@$xr) { $xrr += $_ * $b; $b *= $BASE; } # $b = 1; $yrr = 0; foreach (@$yr) { $yrr += $_ * $b; $b *= $BASE; } # $c->_add($x, $c->_mul(_new( $c, ($xrr | $yrr) ), $m) ); - $c->_add($z, $c->_mul([ 0 + $xr->[0] | 0 + $yr->[0] ], $m)); $c->_mul($m, $mask); } @@ -2191,94 +2081,70 @@ sub _as_hex { # convert a decimal number to hex (ref to array, return ref to string) my ($c, $x) = @_; - # fits into one element (handle also 0x0 case) - return sprintf("0x%x", $x->[0]) if @$x == 1; + return "0x0" if @$x == 1 && $x->[0] == 0; my $x1 = $c->_copy($x); + my $x10000 = [ 0x10000 ]; + my $es = ''; - my ($xr, $h, $x10000); - if ($] >= 5.006) { - $x10000 = [ 0x10000 ]; - $h = 'h4'; - } else { - $x10000 = [ 0x1000 ]; - $h = 'h3'; - } - while (@$x1 != 1 || $x1->[0] != 0) # _is_zero() - { + my $xr; + until (@$x1 == 1 && $x1->[0] == 0) { # _is_zero() ($x1, $xr) = $c->_div($x1, $x10000); - $es .= unpack($h, pack('V', $xr->[0])); + $es = sprintf('%04x', $xr->[0]) . $es; } - $es = reverse $es; - $es =~ s/^[0]+//; # strip leading zeros - '0x' . $es; # return result prepended with 0x + #$es = reverse $es; + $es =~ s/^0*/0x/; + return $es; } sub _as_bin { # convert a decimal number to bin (ref to array, return ref to string) my ($c, $x) = @_; - # fits into one element (and Perl recent enough), handle also 0b0 case - # handle zero case for older Perls - if ($] <= 5.005 && @$x == 1 && $x->[0] == 0) { - my $t = '0b0'; - return $t; - } - if (@$x == 1 && $] >= 5.006) { - my $t = sprintf("0b%b", $x->[0]); - return $t; - } + return "0b0" if @$x == 1 && $x->[0] == 0; + my $x1 = $c->_copy($x); + my $x10000 = [ 0x10000 ]; + my $es = ''; - my ($xr, $b, $x10000); - if ($] >= 5.006) { - $x10000 = [ 0x10000 ]; - $b = 'b16'; - } else { - $x10000 = [ 0x1000 ]; - $b = 'b12'; - } - while (!(@$x1 == 1 && $x1->[0] == 0)) # _is_zero() - { + my $xr; + + until (@$x1 == 1 && $x1->[0] == 0) { # _is_zero() ($x1, $xr) = $c->_div($x1, $x10000); - $es .= unpack($b, pack('v', $xr->[0])); + $es = sprintf('%016b', $xr->[0]) . $es; } - $es = reverse $es; - $es =~ s/^[0]+//; # strip leading zeros - '0b' . $es; # return result prepended with 0b + $es =~ s/^0*/0b/; + return $es; } sub _as_oct { # convert a decimal number to octal (ref to array, return ref to string) my ($c, $x) = @_; - # fits into one element (handle also 0 case) - return sprintf("0%o", $x->[0]) if @$x == 1; + return "00" if @$x == 1 && $x->[0] == 0; my $x1 = $c->_copy($x); + my $x1000 = [ 0100000 ]; + my $es = ''; my $xr; - my $x1000 = [ 0100000 ]; - while (@$x1 != 1 || $x1->[0] != 0) # _is_zero() - { + until (@$x1 == 1 && $x1->[0] == 0) { # _is_zero() ($x1, $xr) = $c->_div($x1, $x1000); - $es .= reverse sprintf("%05o", $xr->[0]); + $es = sprintf("%05o", $xr->[0]) . $es; } - $es = reverse $es; - $es =~ s/^0+//; # strip leading zeros - '0' . $es; # return result prepended with 0 + $es =~ s/^0*/0/; # excactly one leading zero + return $es; } sub _from_oct { # convert a octal number to decimal (string, return ref to array) my ($c, $os) = @_; - # for older Perls, play safe - my $m = [ 0100000 ]; - my $d = 5; # 5 digits at a time + my $m = $c->_new(010000000000); # 30 bits at a time (<32 bits!) + my $d = 10; # 10 octal digits at a time my $mul = $c->_one(); my $x = $c->_zero(); @@ -2291,7 +2157,7 @@ sub _from_oct { $val = CORE::oct($val); $i -= $d; $len --; - my $adder = [ $val ]; + my $adder = $c -> _new($val); $c->_add($x, $c->_mul($adder, $mul)) if $val != 0; $c->_mul($mul, $m) if $len >= 0; # skip last mul } @@ -2302,8 +2168,8 @@ sub _from_hex { # convert a hex number to decimal (string, return ref to array) my ($c, $hs) = @_; - my $m = $c->_new(0x10000000); # 28 bit at a time (<32 bit!) - my $d = 7; # 7 digits at a time + my $m = $c->_new(0x10000000); # 28 bit at a time (<32 bit!) + my $d = 7; # 7 hexadecimal digits at a time my $mul = $c->_one(); my $x = $c->_zero(); @@ -2316,7 +2182,7 @@ sub _from_hex { $val = CORE::hex($val); # hex does not like wrong chars $i -= $d; $len --; - my $adder = [ $val ]; + my $adder = $c->_new($val); # if the resulting number was to big to fit into one element, create a # two-element version (bug found by Mark Lakata - Thanx!) if (CORE::length($val) > $BASE_LEN) { @@ -2471,7 +2337,7 @@ sub _gcd { =head1 NAME -Math::BigInt::Calc - Pure Perl module to support Math::BigInt +Math::BigInt::Calc - pure Perl module to support Math::BigInt =head1 SYNOPSIS @@ -2484,25 +2350,55 @@ Math::BigInt::Calc - Pure Perl module to support Math::BigInt # to use it with Math::BigRat use Math::BigRat lib => 'Calc'; + # explicitly set base length and whether to "use integer" + use Math::BigInt::Calc base_len => 4, use_int => 1; + use Math::BigInt lib => 'Calc'; + =head1 DESCRIPTION Math::BigInt::Calc inherits from Math::BigInt::Lib. -In this library, the numbers are represented in base B = 10**N, where N is the -largest possible value that does not cause overflow in the intermediate -computations. The base B elements are stored in an array, with the least -significant element stored in array element zero. There are no leading zero -elements, except a single zero element when the number is zero. +In this library, the numbers are represented interenally in base B = 10**N, +where N is the largest possible integer that does not cause overflow in the +intermediate computations. The base B elements are stored in an array, with the +least significant element stored in array element zero. There are no leading +zero elements, except a single zero element when the number is zero. For +instance, if B = 10000, the number 1234567890 is represented internally as +[7890, 3456, 12]. + +=head1 OPTIONS + +When the module is loaded, it computes the maximum exponent, i.e., power of 10, +that can be used with and without "use integer" in the computations. The default +is to use this maximum exponent. If the combination of the 'base_len' value and +the 'use_int' value exceeds the maximum value, an error is thrown. + +=over 4 + +=item base_len + +The base length can be specified explicitly with the 'base_len' option. The +value must be a positive integer. + + use Math::BigInt::Calc base_len => 4; # use 10000 as internal base + +=item use_int + +This option is used to specify whether "use integer" should be used in the +internal computations. The value is interpreted as a boolean value, so use 0 or +"" for false and anything else for true. If the 'base_len' is not specified +together with 'use_int', the current value for the base length is used. + + use Math::BigInt::Calc use_int => 1; # use "use integer" internally -For instance, if B = 10000, the number 1234567890 is represented internally -as [7890, 3456, 12]. +=back =head1 SEE ALSO L<Math::BigInt::Lib> for a description of the API. -Alternative libraries L<Math::BigInt::FastCalc>, L<Math::BigInt::GMP>, and -L<Math::BigInt::Pari>. +Alternative libraries L<Math::BigInt::FastCalc>, L<Math::BigInt::GMP>, +L<Math::BigInt::Pari>, L<Math::BigInt::GMPz>, and L<Math::BigInt::BitVect>. Some of the modules that use these libraries L<Math::BigInt>, L<Math::BigFloat>, and L<Math::BigRat>. diff --git a/cpan/Math-BigInt/lib/Math/BigInt/Lib.pm b/cpan/Math-BigInt/lib/Math/BigInt/Lib.pm index fde281297f..ee5577c6dd 100644 --- a/cpan/Math-BigInt/lib/Math/BigInt/Lib.pm +++ b/cpan/Math-BigInt/lib/Math/BigInt/Lib.pm @@ -4,7 +4,7 @@ use 5.006001; use strict; use warnings; -our $VERSION = '1.999818'; +our $VERSION = '1.999823'; use Carp; @@ -88,7 +88,7 @@ use overload $x = $_[0]; $y = ref($_[1]) ? $class -> _num($_[1]) : $_[1]; } - return $class -> _blsft($x, $y); + return $class -> _lsft($x, $y); }, '>>' => sub { @@ -101,7 +101,7 @@ use overload $x = $class -> _copy($_[0]); $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); } - return $class -> _brsft($x, $y); + return $class -> _rsft($x, $y); }, # overload key: num_comparison @@ -573,23 +573,54 @@ sub _nok { return $n; } +#sub _fac { +# # factorial +# my ($class, $x) = @_; +# +# my $two = $class -> _two(); +# +# if ($class -> _acmp($x, $two) < 0) { +# return $class -> _one(); +# } +# +# my $i = $class -> _copy($x); +# while ($class -> _acmp($i, $two) > 0) { +# $i = $class -> _dec($i); +# $x = $class -> _mul($x, $i); +# } +# +# return $x; +#} + sub _fac { # factorial my ($class, $x) = @_; - my $two = $class -> _two(); + # This is an implementation of the split recursive algorithm. See + # http://www.luschny.de/math/factorial/csharp/FactorialSplit.cs.html - if ($class -> _acmp($x, $two) < 0) { - return $class -> _one(); - } + my $p = $class -> _one(); + my $r = $class -> _one(); + my $two = $class -> _two(); - my $i = $class -> _copy($x); - while ($class -> _acmp($i, $two) > 0) { - $i = $class -> _dec($i); - $x = $class -> _mul($x, $i); + my ($log2n) = $class -> _log_int($class -> _copy($x), $two); + my $h = $class -> _zero(); + my $shift = $class -> _zero(); + my $k = $class -> _one(); + + while ($class -> _acmp($h, $x)) { + $shift = $class -> _add($shift, $h); + $h = $class -> _rsft($class -> _copy($x), $log2n, $two); + $log2n = $class -> _dec($log2n) if !$class -> _is_zero($log2n); + my $high = $class -> _copy($h); + $high = $class -> _dec($high) if $class -> _is_even($h); + while ($class -> _acmp($k, $high)) { + $k = $class -> _add($k, $two); + $p = $class -> _mul($p, $k); + } + $r = $class -> _mul($r, $p); } - - return $x; + return $class -> _lsft($r, $shift, $two); } sub _dfac { @@ -725,7 +756,7 @@ sub _sqrt { # # x(i+1) = x(i) - f(x(i)) / f'(x(i)) # = x(i) - (x(i)^2 - y) / (2 * x(i)) # use if x(i)^2 > y - # = y(i) + (y - x(i)^2) / (2 * x(i)) # use if x(i)^2 < y + # = x(i) + (y - x(i)^2) / (2 * x(i)) # use if x(i)^2 < y # Determine if x, our guess, is too small, correct, or too large. @@ -1433,7 +1464,9 @@ sub _to_base { my $collseq; if (@_) { - $collseq = shift(); + $collseq = shift; + croak "The collation sequence must be a non-empty string" + unless defined($collseq) && length($collseq); } else { if ($class -> _acmp($base, $class -> _new("94")) <= 0) { $collseq = '0123456789' # 48 .. 57 @@ -1461,10 +1494,40 @@ sub _to_base { my $chr = $collseq[$num]; $str = $chr . $str; } - return "0" unless length $str; + return $collseq[0] unless length $str; return $str; } +sub _to_base_num { + # Convert the number to an array of integers in any base. + my ($class, $x, $base) = @_; + + # Make sure the base is an object and >= 2. + $base = $class -> _new($base) unless ref($base); + my $two = $class -> _two(); + croak "base must be >= 2" unless $class -> _acmp($base, $two) >= 0; + + my $out = []; + my $xcopy = $class -> _copy($x); + my $rem; + + # Do all except the last (most significant) element. + until ($class -> _acmp($xcopy, $base) < 0) { + ($xcopy, $rem) = $class -> _div($xcopy, $base); + unshift @$out, $rem; + } + + # Do the last (most significant element). + unless ($class -> _is_zero($xcopy)) { + unshift @$out, $xcopy; + } + + # $out is empty if $x is zero. + unshift @$out, $class -> _zero() unless @$out; + + return $out; +} + sub _from_hex { # Convert a string of hexadecimal digits to a number. @@ -1622,6 +1685,32 @@ sub _from_base { return $x; } +sub _from_base_num { + # Convert an array in the given base to a number. + my ($class, $in, $base) = @_; + + # Make sure the base is an object and >= 2. + $base = $class -> _new($base) unless ref($base); + my $two = $class -> _two(); + croak "base must be >= 2" unless $class -> _acmp($base, $two) >= 0; + + # @$in = map { ref($_) ? $_ : $class -> _new($_) } @$in; + + my $ele = $in -> [0]; + + $ele = $class -> _new($ele) unless ref($ele); + my $x = $class -> _copy($ele); + + for my $i (1 .. $#$in) { + $x = $class -> _mul($x, $base); + $ele = $in -> [$i]; + $ele = $class -> _new($ele) unless ref($ele); + $x = $class -> _add($x, $ele); + } + + return $x; +} + ############################################################################## # special modulus functions @@ -1786,8 +1875,6 @@ sub _lucas { return @y; } - require Scalar::Util; - # In scalar context use that lucas(n) = fib(n-1) + fib(n+1). # # Remember that _fib() behaves differently in scalar context and list @@ -1795,8 +1882,8 @@ sub _lucas { return $class -> _two() if $n == 0; - return $class -> _add(scalar $class -> _fib($n - 1), - scalar $class -> _fib($n + 1)); + return $class -> _add(scalar($class -> _fib($n - 1)), + scalar($class -> _fib($n + 1))); } sub _fib { @@ -2035,6 +2122,16 @@ Some more examples, all returning 250: $x = $class -> _from_base("42", 62) $x = $class -> _from_base("2!", 94) +=item CLASS-E<gt>_from_base_num(ARRAY, BASE) + +Returns an object given an array of values and a base. This method is +equivalent to C<_from_base()>, but works on numbers in an array rather than +characters in a string. Unlike C<_from_base()>, all input values may be +arbitrarily large. + + $x = $class -> _from_base_num([1, 1, 0, 1], 2) # $x is 13 + $x = $class -> _from_base_num([3, 125, 39], 128) # $x is 65191 + =back =head3 Mathematical functions @@ -2268,6 +2365,16 @@ COLLSEQ. See _from_base() for more information. +=item CLASS-E<gt>_to_base_num(OBJ, BASE) + +Converts the given number to the given base. This method is equivalent to +C<_to_base()>, but returns numbers in an array rather than characters in a +string. In the output, the first element is the most significant. Unlike +C<_to_base()>, all input values may be arbitrarily large. + + $x = $class -> _to_base_num(13, 2) # $x is [1, 1, 0, 1] + $x = $class -> _to_base_num(65191, 128) # $x is [3, 125, 39] + =item CLASS-E<gt>_as_bin(OBJ) Like C<_to_bin()> but with a '0b' prefix. @@ -2460,7 +2567,7 @@ the same terms as Perl itself. =head1 AUTHOR -Peter John Acklam, E<lt>pjacklam@online.noE<gt> +Peter John Acklam, E<lt>pjacklam@gmail.comE<gt> Code and documentation based on the Math::BigInt::Calc module by Tels E<lt>nospam-abuse@bloodgate.comE<gt> diff --git a/cpan/Math-BigInt/t/Math/BigInt/BareCalc.pm b/cpan/Math-BigInt/t/Math/BigInt/BareCalc.pm index 86522d5d63..c6ef25d2f1 100644 --- a/cpan/Math-BigInt/t/Math/BigInt/BareCalc.pm +++ b/cpan/Math-BigInt/t/Math/BigInt/BareCalc.pm @@ -9,7 +9,7 @@ our $VERSION = '1.999803'; # Package to to test Bigint's simulation of Calc -use Math::BigInt::Calc '1.9998'; +use Math::BigInt::Calc 1.9998; our @ISA = qw(Math::BigInt::Calc); print "# BareCalc using Calc v", Math::BigInt::Calc -> VERSION, "\n"; diff --git a/cpan/Math-BigInt/t/Math/BigInt/Lib/Minimal.pm b/cpan/Math-BigInt/t/Math/BigInt/Lib/Minimal.pm index f521e52e23..2955258b39 100644 --- a/cpan/Math-BigInt/t/Math/BigInt/Lib/Minimal.pm +++ b/cpan/Math-BigInt/t/Math/BigInt/Lib/Minimal.pm @@ -12,8 +12,7 @@ use Math::BigInt::Lib; our @ISA = ('Math::BigInt::Lib'); -#my $BASE_LEN = 4; -my $BASE_LEN = 9; +my $BASE_LEN = 5; my $BASE = 0 + ("1" . ("0" x $BASE_LEN)); my $MAX_VAL = $BASE - 1; @@ -25,8 +24,8 @@ sub _new { my $p = int($n / $BASE_LEN); my $q = $n % $BASE_LEN; - my $format = $] < 5.9008 ? "a$BASE_LEN" x $p - : "(a$BASE_LEN)*"; + my $format = $] < 5.008 ? "a$BASE_LEN" x $p + : "(a$BASE_LEN)*"; $format = "a$q" . $format if $q > 0; my $self = [ reverse(map { 0 + $_ } unpack($format, $str)) ]; @@ -34,7 +33,7 @@ sub _new { } ############################################################################## -# convert back to string and number +# convert to string sub _str { my ($class, $x) = @_; diff --git a/cpan/Math-BigInt/t/bare_mbf.t b/cpan/Math-BigInt/t/bare_mbf.t index c8184cb861..7c1a121454 100644 --- a/cpan/Math-BigInt/t/bare_mbf.t +++ b/cpan/Math-BigInt/t/bare_mbf.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 2830; +use Test::More tests => 3076; use lib 't'; diff --git a/cpan/Math-BigInt/t/bare_mbi.t b/cpan/Math-BigInt/t/bare_mbi.t index 7c24404738..3ab9f991bb 100644 --- a/cpan/Math-BigInt/t/bare_mbi.t +++ b/cpan/Math-BigInt/t/bare_mbi.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 4038; # tests in require'd file +use Test::More tests => 4292; # tests in require'd file use lib 't'; diff --git a/cpan/Math-BigInt/t/bigfltpm.inc b/cpan/Math-BigInt/t/bigfltpm.inc index af6e422e88..0f5e9e4e83 100644 --- a/cpan/Math-BigInt/t/bigfltpm.inc +++ b/cpan/Math-BigInt/t/bigfltpm.inc @@ -49,7 +49,9 @@ while (<DATA>) { $try .= qq| \$x->accuracy($args[1]); \$x->precision($args[2]);|; $try .= ' $x->bstr();'; # some unary ops - } elsif ($f =~ /^b(nan|floor|ceil|int|sstr|neg|abs|sgn|inc|dec|not|sqrt|exp|fac)$/) { + } elsif ($f =~ /^b(nan|floor|ceil|int|sstr|neg|abs|sgn|inc|dec|not|sqrt|exp)$/) { + $try .= qq| \$x->$f();|; + } elsif ($f =~ /^b[dt]?fac$/) { $try .= qq| \$x->$f();|; } elsif ($f =~ /^(numify|length|as_number)$/) { $try .= qq| \$x->$f();|; @@ -113,6 +115,8 @@ while (<DATA>) { $try .= ' $x->bpow($y);'; } elsif ($f eq "bnok") { $try .= ' $x->bnok($y);'; + } elsif ($f eq "bmfac") { + $try .= ' $x->bmfac($y);'; } elsif ($f eq "bcos") { $try .= ' $x->bcos($y);'; } elsif ($f eq "bsin") { @@ -515,6 +519,9 @@ abc:+0:NaN $div_scale = 40 &bcos +NaN:10:NaN ++inf:10:NaN +-inf:10:NaN 1.2:10:0.3623577545 2.4:12:-0.737393715541 0:10:1 @@ -523,6 +530,9 @@ $div_scale = 40 1:12:0.540302305868 &bsin +NaN:10:NaN ++inf:10:NaN +-inf:10:NaN 1:10:0.8414709848 0:10:0 0:20:0 @@ -1981,10 +1991,10 @@ abc:1:abc:NaN 3:-1:0 &bfac -Nanfac:NaN --1:NaN +invalid:NaN +inf:inf -inf:NaN +-1:NaN 0:1 1:1 2:2 @@ -1992,15 +2002,22 @@ Nanfac:NaN 4:24 5:120 6:720 +7:5040 +8:40320 +9:362880 10:3628800 11:39916800 12:479001600 +20:2432902008176640000 +22:1124000727777607680000 +69:171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000 &bdfac NaN:NaN --1:NaN +inf:inf -inf:NaN +-2:NaN +-1:1 0:1 1:1 2:2 @@ -2015,6 +2032,126 @@ NaN:NaN 11:10395 12:46080 +&btfac +NaN:NaN ++inf:inf +-inf:NaN +-3:NaN +-2:1 +-1:1 +0:1 +1:1 +2:2 +3:3 +4:4 +5:10 +6:18 +7:28 +8:80 +9:162 +10:280 +11:880 +12:1944 + +&bmfac + +7:-inf:NaN +7:-1:NaN +7:0:NaN +7:2.5:NaN +7:inf:7 +7:NaN:NaN + +NaN:1:NaN ++inf:1:inf +-inf:1:NaN +-1:1:NaN +0:1:1 +1:1:1 +2:1:2 +3:1:6 +4:1:24 +5:1:120 +6:1:720 +7:1:5040 +8:1:40320 +9:1:362880 +10:1:3628800 + +NaN:2:NaN ++inf:2:inf +-inf:2:NaN +-2:2:NaN +-1:2:1 +0:2:1 +1:2:1 +2:2:2 +3:2:3 +4:2:8 +5:2:15 +6:2:48 +7:2:105 +8:2:384 +9:2:945 +10:2:3840 + +NaN:3:NaN ++inf:3:inf +-inf:3:NaN +-3:3:NaN +-2:3:1 +-1:3:1 +0:3:1 +1:3:1 +2:3:2 +3:3:3 +4:3:4 +5:3:10 +6:3:18 +7:3:28 +8:3:80 +9:3:162 +10:3:280 + +NaN:4:NaN ++inf:4:inf +-inf:4:NaN +-4:4:NaN +-3:4:1 +-2:4:1 +-1:4:1 +0:4:1 +1:4:1 +2:4:2 +3:4:3 +4:4:4 +5:4:5 +6:4:12 +7:4:21 +8:4:32 +9:4:45 +10:4:120 + +NaN:5:NaN ++inf:5:inf +-inf:5:NaN +-5:5:NaN +-4:5:1 +-3:5:1 +-2:5:1 +-1:5:1 +0:5:1 +1:5:1 +2:5:2 +3:5:3 +4:5:4 +5:5:5 +6:5:6 +7:5:14 +8:5:24 +9:5:36 +10:5:50 + &broot # sqrt() +0:2:0 diff --git a/cpan/Math-BigInt/t/bigfltpm.t b/cpan/Math-BigInt/t/bigfltpm.t index 8b0079fedc..fb68c05530 100644 --- a/cpan/Math-BigInt/t/bigfltpm.t +++ b/cpan/Math-BigInt/t/bigfltpm.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 2830 # tests in require'd file +use Test::More tests => 3076 # tests in require'd file + 19; # tests in this file use Math::BigInt only => 'Calc'; diff --git a/cpan/Math-BigInt/t/bigintc-import.t b/cpan/Math-BigInt/t/bigintc-import.t new file mode 100644 index 0000000000..161328e595 --- /dev/null +++ b/cpan/Math-BigInt/t/bigintc-import.t @@ -0,0 +1,39 @@ +#!perl + +use strict; +use warnings; + +use Test::More tests => 4; + +use Math::BigInt::Calc base_len => 1, use_int => 0; + +my ($BASE_LEN, $BASE, $AND_BITS, $XOR_BITS, $OR_BITS, + $BASE_LEN_SMALL, $MAX_VAL, + $MAX_BITS, $MAX_EXP_F, $MAX_EXP_I, $USE_INT) + = Math::BigInt::Calc->_base_len(); + +diag(<<"EOF"); + +BASE_LEN = $BASE_LEN +BASE = $BASE +MAX_VAL = $MAX_VAL +AND_BITS = $AND_BITS +XOR_BITS = $XOR_BITS +OR_BITS = $OR_BITS +MAX_EXP_F = $MAX_EXP_F +MAX_EXP_I = $MAX_EXP_I +USE_INT = $USE_INT +EOF + +cmp_ok($BASE_LEN, "==", 1, '$BASE_LEN is 1'); +cmp_ok($USE_INT, "==", 0, '$USE_INT is 0'); + +my $LIB = 'Math::BigInt::Calc'; + +my $x = $LIB -> _new("31415926535897932384626433832"); +my $str = $LIB -> _str($x); +is($str, "31415926535897932384626433832", + "string representation of $LIB object"); + +is("[ @$x ]", "[ 2 3 8 3 3 4 6 2 6 4 8 3 2 3 9 7 9 8 5 3 5 6 2 9 5 1 4 1 3 ]", + "internal representation of $LIB object"); diff --git a/cpan/Math-BigInt/t/bigintc.t b/cpan/Math-BigInt/t/bigintc.t index f9c16d233b..87384f7968 100644 --- a/cpan/Math-BigInt/t/bigintc.t +++ b/cpan/Math-BigInt/t/bigintc.t @@ -1,31 +1,40 @@ #!perl +# Test Math::BigInt::Calc + use strict; use warnings; -use Test::More tests => 460; +use Test::More tests => 524; use Math::BigInt::Calc; -my ($BASE_LEN, undef, $AND_BITS, $XOR_BITS, $OR_BITS, - $BASE_LEN_SMALL, $MAX_VAL) - = Math::BigInt::Calc->_base_len(); +my ($BASE_LEN, $BASE, $AND_BITS, $XOR_BITS, $OR_BITS, + $BASE_LEN_SMALL, $MAX_VAL, + $MAX_BITS, $MAX_EXP_F, $MAX_EXP_I, $USE_INT) + = Math::BigInt::Calc -> _base_len(); -print "# BASE_LEN = $BASE_LEN\n"; -print "# MAX_VAL = $MAX_VAL\n"; -print "# AND_BITS = $AND_BITS\n"; -print "# XOR_BITS = $XOR_BITS\n"; -print "# IOR_BITS = $OR_BITS\n"; +diag(<<"EOF"); -# testing of Math::BigInt::Calc +BASE_LEN = $BASE_LEN +BASE = $BASE +MAX_VAL = $MAX_VAL +AND_BITS = $AND_BITS +XOR_BITS = $XOR_BITS +OR_BITS = $OR_BITS +MAX_EXP_F = $MAX_EXP_F +MAX_EXP_I = $MAX_EXP_I +USE_INT = $USE_INT +EOF -my $LIB = 'Math::BigInt::Calc'; # pass classname to sub's +my $LIB = 'Math::BigInt::Calc'; +my $REF = 'Math::BigInt::Calc'; # _new and _str my $x = $LIB->_new("123"); my $y = $LIB->_new("321"); -is(ref($x), "Math::BigInt::Calc", q|ref($x) is an Math::BigInt::Calc|); +is(ref($x), $REF, q|ref($x) is a $REF|); is($LIB->_str($x), 123, qq|$LIB->_str(\$x) = 123|); is($LIB->_str($y), 321, qq|$LIB->_str(\$y) = 321|); @@ -80,46 +89,38 @@ is($LIB->_str($rr), 2, qq|$LIB->_str(\$rr) = 2|); # is_zero, _is_one, _one, _zero -is($LIB->_is_zero($x) || 0, 0, qq/$LIB->_is_zero(\$x) || 0 = 0/); -is($LIB->_is_one($x) || 0, 0, qq/$LIB->_is_one(\$x) || 0 = 0/); +ok(! $LIB->_is_zero($x), qq|$LIB->_is_zero(\$x)|); +ok(! $LIB->_is_one($x), qq|$LIB->_is_one(\$x)|); is($LIB->_str($LIB->_zero()), "0", qq|$LIB->_str($LIB->_zero()) = "0"|); is($LIB->_str($LIB->_one()), "1", qq|$LIB->_str($LIB->_one()) = "1"|); # _two() and _ten() -is($LIB->_str($LIB->_two()), "2", qq|$LIB->_str($LIB->_two()) = "2"|); -is($LIB->_str($LIB->_ten()), "10", qq|$LIB->_str($LIB->_ten()) = "10"|); -is($LIB->_is_ten($LIB->_two()), 0, qq|$LIB->_is_ten($LIB->_two()) = 0|); -is($LIB->_is_two($LIB->_two()), 1, qq|$LIB->_is_two($LIB->_two()) = 1|); -is($LIB->_is_ten($LIB->_ten()), 1, qq|$LIB->_is_ten($LIB->_ten()) = 1|); -is($LIB->_is_two($LIB->_ten()), 0, qq|$LIB->_is_two($LIB->_ten()) = 0|); - -is($LIB->_is_one($LIB->_one()), 1, qq|$LIB->_is_one($LIB->_one()) = 1|); -is($LIB->_is_one($LIB->_two()), 0, qq|$LIB->_is_one($LIB->_two()) = 0|); -is($LIB->_is_one($LIB->_ten()), 0, qq|$LIB->_is_one($LIB->_ten()) = 0|); +is($LIB->_str($LIB->_two()), "2", qq|$LIB->_str($LIB->_two()) = "2"|); +is($LIB->_str($LIB->_ten()), "10", qq|$LIB->_str($LIB->_ten()) = "10"|); -is($LIB->_is_one($LIB->_zero()) || 0, 0, - qq/$LIB->_is_one($LIB->_zero()) || 0 = 0/); +ok(! $LIB->_is_ten($LIB->_two()), qq|$LIB->_is_ten($LIB->_two()) is false|); +ok( $LIB->_is_two($LIB->_two()), qq|$LIB->_is_two($LIB->_two()) is true|); +ok( $LIB->_is_ten($LIB->_ten()), qq|$LIB->_is_ten($LIB->_ten()) is true|); +ok(! $LIB->_is_two($LIB->_ten()), qq|$LIB->_is_two($LIB->_ten()) is false|); -is($LIB->_is_zero($LIB->_zero()), 1, - qq|$LIB->_is_zero($LIB->_zero()) = 1|); +ok( $LIB->_is_one($LIB->_one()), qq|$LIB->_is_one($LIB->_one()) is true|); +ok(! $LIB->_is_one($LIB->_two()), qq|$LIB->_is_one($LIB->_two()) is false|); +ok(! $LIB->_is_one($LIB->_ten()), qq|$LIB->_is_one($LIB->_ten()) is false|); -is($LIB->_is_zero($LIB->_one()) || 0, 0, - qq/$LIB->_is_zero($LIB->_one()) || 0 = 0/); +ok(! $LIB->_is_one($LIB->_zero()), qq/$LIB->_is_one($LIB->_zero()) is false/); +ok( $LIB->_is_zero($LIB->_zero()), qq|$LIB->_is_zero($LIB->_zero()) is true|); +ok(! $LIB->_is_zero($LIB->_one()), qq/$LIB->_is_zero($LIB->_one()) is false/); # is_odd, is_even -is($LIB->_is_odd($LIB->_one()), 1, - qq/$LIB->_is_odd($LIB->_one()) = 1/); -is($LIB->_is_odd($LIB->_zero()) || 0, 0, - qq/$LIB->_is_odd($LIB->_zero()) || 0 = 0/); -is($LIB->_is_even($LIB->_one()) || 0, 0, - qq/$LIB->_is_even($LIB->_one()) || 0 = 0/); -is($LIB->_is_even($LIB->_zero()), 1, - qq/$LIB->_is_even($LIB->_zero()) = 1/); +ok( $LIB->_is_odd($LIB->_one()), qq/$LIB->_is_odd($LIB->_one()) is true/); +ok(! $LIB->_is_odd($LIB->_zero()), qq/$LIB->_is_odd($LIB->_zero()) is false/); +ok(! $LIB->_is_even($LIB->_one()), qq/$LIB->_is_even($LIB->_one()) is false/); +ok( $LIB->_is_even($LIB->_zero()), qq/$LIB->_is_even($LIB->_zero()) is true/); -# _len +# _alen and _len for my $method (qw/_alen _len/) { $x = $LIB->_new("1"); @@ -348,8 +349,7 @@ is($LIB->_str($y), 123, qq|$LIB->_str(\$y) = 123|); foreach (qw/1 12 123 1234 12345 1234567 12345678 123456789 1234567890/) { $x = $LIB->_new("$_"); - is(ref($x), "Math::BigInt::Calc", - q|ref($x) = "Math::BigInt::Calc"|); + is(ref($x), $REF, q|ref($x) = "$REF"|); is($LIB->_str($x), "$_", qq|$LIB->_str(\$x) = "$_"|); $x = $LIB->_num($x); @@ -524,7 +524,6 @@ $LIB->_fac($x); is($LIB->_str($x), "6227020800", qq|$LIB->_str(\$x) = "6227020800"|); -############################################################################## # _inc and _dec for (qw/1 11 121 1231 12341 1234561 12345671 123456781 1234567891/) { @@ -545,13 +544,30 @@ for (qw/19 119 1219 12319 1234519 12345619 123456719 1234567819/) { is($LIB->_str($x), $_, qq|$LIB->_str(\$x) = $_|); } -for (qw/999 9999 99999 9999999 99999999 999999999 9999999999 99999999999/) { - $x = $LIB->_new("$_"); +for (1 .. 20) { + my $p = "9" x $_; # = $q - 1 + my $q = "1" . ("0" x $_); # = $p + 1 + + $x = $LIB->_new("$p"); $LIB->_inc($x); - my $expected = '1' . '0' x (length($_)); - is($LIB->_str($x), $expected, qq|$LIB->_str(\$x) = $expected|); + is($LIB->_str($x), $q, qq|\$x = $LIB->_new("$p"); $LIB->_inc()|); + + $x = $LIB->_new("$q"); $LIB->_dec($x); - is($LIB->_str($x), $_, qq|$LIB->_str(\$x) = $_|); + is($LIB->_str($x), $p, qq|\$x = $LIB->_new("$q"); $LIB->_dec()|); +} + +for (1 .. 20) { + my $p = "1" . ("0" x $_); # = $q - 1 + my $q = "1" . ("0" x ($_ - 1)) . "1"; # = $p + 1 + + $x = $LIB->_new("$p"); + $LIB->_inc($x); + is($LIB->_str($x), $q, qq|\$x = $LIB->_new("$p"); $LIB->_inc()|); + + $x = $LIB->_new("$q"); + $LIB->_dec($x); + is($LIB->_str($x), $p, qq|\$x = $LIB->_new("$q"); $LIB->_dec()|); } $x = $LIB->_new("1000"); @@ -560,11 +576,7 @@ is($LIB->_str($x), "1001", qq|$LIB->_str(\$x) = "1001"|); $LIB->_dec($x); is($LIB->_str($x), "1000", qq|$LIB->_str(\$x) = "1000"|); -my $BL; -{ - no strict 'refs'; - $BL = &{"$LIB"."::_base_len"}(); -} +my $BL = $LIB -> _base_len(); $x = '1' . '0' x $BL; $z = '1' . '0' x ($BL - 1); @@ -764,7 +776,3 @@ is($LIB->_check(123), "123 is not a reference", is(@$x, 1, q|@$x = 1|); is($x->[0], 0, q|$x->[0] = 0|); } - -# done - -1; diff --git a/cpan/Math-BigInt/t/bigintpm.inc b/cpan/Math-BigInt/t/bigintpm.inc index 9dd331ab17..d59a3f1c68 100644 --- a/cpan/Math-BigInt/t/bigintpm.inc +++ b/cpan/Math-BigInt/t/bigintpm.inc @@ -77,7 +77,9 @@ while (<DATA>) { } elsif ($f eq "bone") { $try .= qq| \$x->bone("$args[1]");|; # some unary ops - } elsif ($f =~ /^b(nan|floor|ceil|int|sstr|neg|abs|sgn|inc|dec|not|sqrt|exp|fac)$/) { + } elsif ($f =~ /^b(nan|floor|ceil|int|sstr|neg|abs|sgn|inc|dec|not|sqrt|exp)$/) { + $try .= " \$x->$f();"; + } elsif ($f =~ /^b[dt]?fac$/) { $try .= " \$x->$f();"; } elsif ($f =~ /^(numify|length|stringify)$/) { $try .= " \$x->$f();"; @@ -159,6 +161,8 @@ while (<DATA>) { } } elsif ($f eq "bnok") { $try .= " \$x->bnok(\$y);"; + } elsif ($f eq "bmfac") { + $try .= " \$x->bmfac(\$y);"; } elsif ($f eq "broot") { $try .= " \$x->broot(\$y);"; } elsif ($f eq "blog") { @@ -814,9 +818,11 @@ SKIP: { $x = '9' x $bl; $x = $CLASS->new($x); - # 999 * 999 => 998 . 001, 9999*9999 => 9998 . 0001 - is($x * $x, '9' x ($bl - 1) . '8' . '0' x ($bl - 1) . '1', - "see if mul shortcut for small numbers works"); + # 999 * 999 => 998 . 001 + # 9999 * 9999 => 9998 . 0001 + $y = '9' x ($bl - 1) . '8' . '0' x ($bl - 1) . '1'; + is($x * $x, $y, + "see if mul shortcut for small numbers works ($x * $x = $y)"); } ########################################################################### @@ -2836,10 +2842,10 @@ abc:NaN,NaN -inf:-inf,inf &bfac --1:NaN -invalid:NaN +NaN:NaN +inf:inf -inf:NaN +-1:NaN 0:1 1:1 2:2 @@ -2857,6 +2863,145 @@ invalid:NaN 22:1124000727777607680000 69:171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000 +&bdfac +NaN:NaN ++inf:inf +-inf:NaN +-2:NaN +-1:1 +0:1 +1:1 +2:2 +3:3 +4:8 +5:15 +6:48 +7:105 +8:384 +9:945 +10:3840 +11:10395 +12:46080 + +&btfac +NaN:NaN ++inf:inf +-inf:NaN +-3:NaN +-2:1 +-1:1 +0:1 +1:1 +2:2 +3:3 +4:4 +5:10 +6:18 +7:28 +8:80 +9:162 +10:280 +11:880 +12:1944 + +&bmfac + +7:-inf:NaN +7:-1:NaN +7:0:NaN +7:inf:7 +7:NaN:NaN + +NaN:1:NaN ++inf:1:inf +-inf:1:NaN +-1:1:NaN +0:1:1 +1:1:1 +2:1:2 +3:1:6 +4:1:24 +5:1:120 +6:1:720 +7:1:5040 +8:1:40320 +9:1:362880 +10:1:3628800 + +NaN:2:NaN ++inf:2:inf +-inf:2:NaN +-2:2:NaN +-1:2:1 +0:2:1 +1:2:1 +2:2:2 +3:2:3 +4:2:8 +5:2:15 +6:2:48 +7:2:105 +8:2:384 +9:2:945 +10:2:3840 + +NaN:3:NaN ++inf:3:inf +-inf:3:NaN +-3:3:NaN +-2:3:1 +-1:3:1 +0:3:1 +1:3:1 +2:3:2 +3:3:3 +4:3:4 +5:3:10 +6:3:18 +7:3:28 +8:3:80 +9:3:162 +10:3:280 + +NaN:4:NaN ++inf:4:inf +-inf:4:NaN +-4:4:NaN +-3:4:1 +-2:4:1 +-1:4:1 +0:4:1 +1:4:1 +2:4:2 +3:4:3 +4:4:4 +5:4:5 +6:4:12 +7:4:21 +8:4:32 +9:4:45 +10:4:120 + +NaN:5:NaN ++inf:5:inf +-inf:5:NaN +-5:5:NaN +-4:5:1 +-3:5:1 +-2:5:1 +-1:5:1 +0:5:1 +1:5:1 +2:5:2 +3:5:3 +4:5:4 +5:5:5 +6:5:6 +7:5:14 +8:5:24 +9:5:36 +10:5:50 + &bpow # abc:12:NaN diff --git a/cpan/Math-BigInt/t/bigintpm.t b/cpan/Math-BigInt/t/bigintpm.t index 7d05dc9e98..7c97920cc5 100644 --- a/cpan/Math-BigInt/t/bigintpm.t +++ b/cpan/Math-BigInt/t/bigintpm.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 4038 # tests in require'd file +use Test::More tests => 4292 # tests in require'd file + 20; # tests in this file use Math::BigInt only => 'Calc'; diff --git a/cpan/Math-BigInt/t/calling.t b/cpan/Math-BigInt/t/calling.t index c3c9affebb..ae584205d0 100644 --- a/cpan/Math-BigInt/t/calling.t +++ b/cpan/Math-BigInt/t/calling.t @@ -6,7 +6,7 @@ use strict; use warnings; use lib 't'; -my $VERSION = '1.999818'; # adjust manually to match latest release +my $VERSION = '1.999823'; # adjust manually to match latest release use Test::More tests => 5; @@ -38,7 +38,7 @@ my ($x, $expected, $try); my $class = 'Math::BigInt'; # test whether use Math::BigInt qw/VERSION/ works -$try = "use $class (" . ($VERSION . '1') .");"; +$try = "use $class " . ($VERSION . '1') . ";"; $try .= ' $x = $class->new(123); $x = "$x";'; eval $try; like($@, qr/ ^ Math::BigInt \s+ ( version \s+ )? \S+ \s+ required--this \s+ @@ -46,25 +46,25 @@ like($@, qr/ ^ Math::BigInt \s+ ( version \s+ )? \S+ \s+ required--this \s+ $try); # test whether fallback to calc works -$try = qq|use $class ($VERSION, "try", "foo, bar, ");| - . qq| $class\->config('lib');|; +$try = qq|use $class $VERSION, "try", "foo, bar, ";| + . qq| $class\->config("lib");|; $expected = eval $try; like($expected, qr/^Math::BigInt::(Fast)?Calc\z/, $try); # test whether constant works or not, also test for qw($VERSION) # bgcd() is present in subclass, too -$try = qq|use $class ($VERSION, "bgcd", ":constant");| +$try = qq|use $class $VERSION, "bgcd", ":constant";| . q| $x = 2**150; bgcd($x); $x = "$x";|; $expected = eval $try; is($expected, "1427247692705959881058285969449495136382746624", $try); # test whether Math::BigInt::Scalar via use works (w/ dff. spellings of calc) -$try = qq|use $class ($VERSION, "lib", "Scalar");| +$try = qq|use $class $VERSION, "lib", "Scalar";| . q| $x = 2**10; $x = "$x";|; $expected = eval $try; is($expected, "1024", $try); -$try = qq|use $class ($VERSION, "lib", "$class\::Scalar");| +$try = qq|use $class $VERSION, "lib", "$class\::Scalar";| . q| $x = 2**10; $x = "$x";|; $expected = eval $try; is($expected, "1024", $try); diff --git a/cpan/Math-BigInt/t/from_base_num-mbi.t b/cpan/Math-BigInt/t/from_base_num-mbi.t new file mode 100644 index 0000000000..b407787274 --- /dev/null +++ b/cpan/Math-BigInt/t/from_base_num-mbi.t @@ -0,0 +1,119 @@ +#!perl + +use strict; +use warnings; + +use Test::More tests => 365; + +my $class; + +BEGIN { $class = 'Math::BigInt'; } +BEGIN { use_ok($class); } + +# For simplicity, we use the same data in the test programs for to_base_num() and +# from_base_num(). + +my @data = + ( + [ 0, 2, [ 0 ] ], + [ 1, 2, [ 1 ] ], + [ 2, 2, [ 1, 0 ] ], + [ 3, 2, [ 1, 1, ] ], + [ 4, 2, [ 1, 0, 0 ] ], + + [ 0, 10, [ 0 ] ], + [ 1, 10, [ 1 ] ], + [ 12, 10, [ 1, 2 ] ], + [ 123, 10, [ 1, 2, 3 ] ], + [ 1230, 10, [ 1, 2, 3, 0 ] ], + + [ "123456789", 100, [ 1, 23, 45, 67, 89 ] ], + + [ "1234567890" x 3, + "987654321", + [ "128", "142745769", "763888804", "574845669" ]], + + [ "1234567890" x 5, + "987654321" x 3, + [ "12499999874843750102814", "447551941015330718793208596" ]], + ); + +for (my $i = 0 ; $i <= $#data ; ++ $i) { + my @in = ($data[$i][2], $data[$i][1]); + my $out = $data[$i][0]; + + # As class method. + + { + for my $base_as_scalar (1, 0) { + for my $elements_as_scalar (1, 0) { + + my $x; + my $test = "\$x = $class -> from_base_num(["; + if ($elements_as_scalar) { + $test .= join ", ", map qq|"$_"|, @{ $in[0] }; + } else { + $test .= join ", ", map qq|$class -> new("$_")|, @{ $in[0] }; + } + $test .= "], "; + if ($base_as_scalar) { + $test .= qq|"$in[1]"|; + } else { + $test .= qq|$class -> new("$in[1]")|; + } + $test .= ")"; + + eval $test; + die "\nThe following test died when eval()'ed. This", + "indicates a broken test\n\n $test\n\nThe error", + " message was\n\n $@\n" if $@; + + subtest $test, sub { + plan tests => 2, + + is(ref($x), $class, "output arg is a $class"); + is($x, $out, 'output arg has the right value'); + }; + } + } + } + + # As instance method. + + { + for my $base_as_scalar (1, 0) { + for my $elements_as_scalar (1, 0) { + for my $str ("-1", "0", "1", "-inf", "+inf", "NaN") { + + my $x; + my $test = qq|\$x = $class -> new("$str");|; + $test .= " \$x -> from_base_num(["; + if ($elements_as_scalar) { + $test .= join ", ", map qq|"$_"|, @{ $in[0] }; + } else { + $test .= join ", ", map qq|$class -> new("$_")|, @{ $in[0] }; + } + $test .= "], "; + if ($base_as_scalar) { + $test .= qq|"$in[1]"|; + } else { + $test .= qq|$class -> new("$in[1]")|; + } + $test .= ")"; + + eval $test; + die "\nThe following test died when eval()'ed. This", + "indicates a broken test\n\n $test\n\nThe error", + " message was\n\n $@\n" if $@; + + subtest $test, sub { + plan tests => 2, + + is(ref($x), $class, "output arg is a $class"); + is($x, $out, 'output arg has the right value'); + }; + } + } + } + } +} diff --git a/cpan/Math-BigInt/t/from_bin-mbf.t b/cpan/Math-BigInt/t/from_bin-mbf.t index 99c02dbf1c..577f8c1a80 100644 --- a/cpan/Math-BigInt/t/from_bin-mbf.t +++ b/cpan/Math-BigInt/t/from_bin-mbf.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 729; +use Test::More tests => 785; my $class; @@ -88,7 +88,9 @@ __END__ 0b0.0p+0:0 0b1100101011111110:51966 +0B1100101011111110:51966 b1100101011111110:51966 +B1100101011111110:51966 1100101011111110:51966 0b1.1001p+3:12.5 @@ -96,7 +98,8 @@ b1100101011111110:51966 -0b.11110001001101010111100110111101111p+31:-2023406814.9375 0b10.0100011010001010110011110001001101p+34:39093746765 +0b.p+0:NaN + NaN:NaN +inf:NaN -inf:NaN -0b.p+0:NaN diff --git a/cpan/Math-BigInt/t/from_bin-mbi.t b/cpan/Math-BigInt/t/from_bin-mbi.t index b473079461..96aa8b3b35 100644 --- a/cpan/Math-BigInt/t/from_bin-mbi.t +++ b/cpan/Math-BigInt/t/from_bin-mbi.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 1373; +use Test::More tests => 1457; my $class; @@ -123,6 +123,10 @@ __END__ 0b100000000000000000000000000000000000000000000000000000000:72057594037927936 0b100000000000000000000000000000000000000000000000000000001:72057594037927937 +0B10:2 +b10:2 +B10:2 + NaN:NaN +inf:NaN -inf:NaN diff --git a/cpan/Math-BigInt/t/from_hex-mbf.t b/cpan/Math-BigInt/t/from_hex-mbf.t index 34b7726b40..cff00bfdf3 100644 --- a/cpan/Math-BigInt/t/from_hex-mbf.t +++ b/cpan/Math-BigInt/t/from_hex-mbf.t @@ -3,12 +3,12 @@ use strict; use warnings; -use Test::More tests => 729; +use Test::More tests => 785; my $class; BEGIN { $class = 'Math::BigFloat'; } -BEGIN { use_ok($class, '1.999710'); } +BEGIN { use_ok($class, '1.999821'); } my @data; my $space = "\t\r\n "; @@ -88,7 +88,9 @@ __END__ 0x0.0p+0:0 0xcafe:51966 +0Xcafe:51966 xcafe:51966 +Xcafe:51966 cafe:51966 0x1.9p+3:12.5 @@ -96,7 +98,8 @@ cafe:51966 -0x.789abcdefp+32:-2023406814.9375 0x12.3456789ap+31:39093746765 +0x.p+0:NaN + NaN:NaN +inf:NaN -inf:NaN -0x.p+0:NaN diff --git a/cpan/Math-BigInt/t/from_hex-mbi.t b/cpan/Math-BigInt/t/from_hex-mbi.t index 246b455ebd..280cf3c74a 100644 --- a/cpan/Math-BigInt/t/from_hex-mbi.t +++ b/cpan/Math-BigInt/t/from_hex-mbi.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 1373; +use Test::More tests => 1457; my $class; @@ -123,6 +123,10 @@ __END__ 0x100000000000000:72057594037927936 0x100000000000001:72057594037927937 +0X10:16 +x10:16 +X10:16 + NaN:NaN +inf:NaN -inf:NaN diff --git a/cpan/Math-BigInt/t/from_oct-mbf.t b/cpan/Math-BigInt/t/from_oct-mbf.t index 685934820c..921ca6878a 100644 --- a/cpan/Math-BigInt/t/from_oct-mbf.t +++ b/cpan/Math-BigInt/t/from_oct-mbf.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 729; +use Test::More tests => 1401; my $class; @@ -69,6 +69,8 @@ for my $entry (@data) { __END__ +# Without "0o" prefix. + 01p+0:1 0.4p+1:1 0.2p+2:1 @@ -96,7 +98,40 @@ __END__ -0.361152746757p+32:-2023406814.9375 44.3212636115p+30:39093746765 +.p+0:NaN + +# With "0o" prefix. + +0o01p+0:1 +0o0.4p+1:1 +0o0.2p+2:1 +0o0.1p+3:1 +0o0.04p+4:1 +0o02p-1:1 +0o04p-2:1 +0o010p-3:1 + +-0o1p+0:-1 + +0o0p+0:0 +0o0p+7:0 +0o0p-7:0 +0o0.p+0:0 +0o.0p+0:0 +0o0.0p+0:0 + +0o145376:51966 +0O145376:51966 +o145376:51966 +O145376:51966 + +0o3.1p+2:12.5 +0o22.15p-1:9.1015625 +-0o0.361152746757p+32:-2023406814.9375 +0o44.3212636115p+30:39093746765 + +0o.p+0:NaN + NaN:NaN +inf:NaN -inf:NaN -.p+0:NaN diff --git a/cpan/Math-BigInt/t/from_oct-mbi.t b/cpan/Math-BigInt/t/from_oct-mbi.t index 6ff650c8b8..5107fd1fb0 100644 --- a/cpan/Math-BigInt/t/from_oct-mbi.t +++ b/cpan/Math-BigInt/t/from_oct-mbi.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 1373; +use Test::More tests => 2745; my $class; @@ -123,6 +123,64 @@ __END__ 4000000000000000000:72057594037927936 4000000000000000001:72057594037927937 +0o0:0 +0o1:1 +0o2:2 +0o3:3 +0o4:4 +0o5:5 +0o6:6 +0o7:7 +0o10:8 +0o11:9 +0o12:10 +0o13:11 +0o14:12 +0o15:13 +0o16:14 +0o17:15 +0o20:16 +0o21:17 + +0o376:254 +0o377:255 +0o400:256 +0o401:257 + +0o177776:65534 +0o177777:65535 +0o200000:65536 +0o200001:65537 + +0o77777776:16777214 +0o77777777:16777215 +0o100000000:16777216 +0o100000001:16777217 + +0o37777777776:4294967294 +0o37777777777:4294967295 +0o40000000000:4294967296 +0o40000000001:4294967297 + +0o17777777777776:1099511627774 +0o17777777777777:1099511627775 +0o20000000000000:1099511627776 +0o20000000000001:1099511627777 + +0o7777777777777776:281474976710654 +0o7777777777777777:281474976710655 +0o10000000000000000:281474976710656 +0o10000000000000001:281474976710657 + +0o3777777777777777776:72057594037927934 +0o3777777777777777777:72057594037927935 +0o4000000000000000000:72057594037927936 +0o4000000000000000001:72057594037927937 + +0O10:8 +o10:8 +O10:8 + NaN:NaN +inf:NaN -inf:NaN diff --git a/cpan/Math-BigInt/t/mbimbf.inc b/cpan/Math-BigInt/t/mbimbf.inc index e291820b58..7a52d73c8a 100644 --- a/cpan/Math-BigInt/t/mbimbf.inc +++ b/cpan/Math-BigInt/t/mbimbf.inc @@ -680,7 +680,8 @@ eval { $x = $mbf->new(1); like($@, qr/^bround\(\) needs positive accuracy/, qq|"\$x->bround(-2)" gives warning as expected|); -# test whether rounding to higher accuracy is no-op +note("test whether rounding to higher accuracy is no-op"); + $x = $mbf->new(1); $x->{_a} = 4; is($x, "1.000", q|$x = "1.000"|); @@ -695,65 +696,76 @@ $x->bround(6); # must be no-op is($x->{_a}, 3, q|$x->{_a} = 3|); is($x, "1230", q|$x = "1230"|); -# bround(n) should set _a +note("bround(n) should set _a"); + $x->bround(2); # smaller works is($x, "1200", q|$x = "1200"|); is($x->{_a}, 2, q|$x->{_a} = 2|); # bround(-n) is undocumented and only used by MBF -# bround(-n) should set _a + +note("bround(-n) should set _a"); + $x = $mbi->new(12345); $x->bround(-1); is($x, "12300", q|$x = "12300"|); is($x->{_a}, 4, q|$x->{_a} = 4|); -# bround(-n) should set _a +note("bround(-n) should set _a"); + $x = $mbi->new(12345); $x->bround(-2); is($x, "12000", q|$x = "12000"|); is($x->{_a}, 3, q|$x->{_a} = 3|); -# bround(-n) should set _a +note("bround(-n) should set _a"); + $x = $mbi->new(12345); $x->{_a} = 5; $x->bround(-3); is($x, "10000", q|$x = "10000"|); is($x->{_a}, 2, q|$x->{_a} = 2|); -# bround(-n) should set _a +note("bround(-n) should set _a"); + $x = $mbi->new(12345); $x->{_a} = 5; $x->bround(-4); is($x, "0", q|$x = "0"|); is($x->{_a}, 1, q|$x->{_a} = 1|); -# bround(-n) should be no-op if n too big +note("bround(-n) should be no-op if n too big"); + $x = $mbi->new(12345); $x->bround(-5); is($x, "0", q|$x = "0"|); # scale to "big" => 0 is($x->{_a}, 0, q|$x->{_a} = 0|); -# bround(-n) should be no-op if n too big +note("bround(-n) should be no-op if n too big"); + $x = $mbi->new(54321); $x->bround(-5); is($x, "100000", q|$x = "100000"|); # used by MBF to round 0.0054321 at 0.0_6_00000 is($x->{_a}, 0, q|$x->{_a} = 0|); -# bround(-n) should be no-op if n too big +note("bround(-n) should be no-op if n too big"); + $x = $mbi->new(54321); $x->{_a} = 5; $x->bround(-6); is($x, "100000", q|$x = "100000"|); # no-op is($x->{_a}, 0, q|$x->{_a} = 0|); -# bround(n) should set _a +note("bround(n) should set _a"); + $x = $mbi->new(12345); $x->{_a} = 5; $x->bround(5); # must be no-op is($x, "12345", q|$x = "12345"|); is($x->{_a}, 5, q|$x->{_a} = 5|); -# bround(n) should set _a +note("bround(n) should set _a"); + $x = $mbi->new(12345); $x->{_a} = 5; $x->bround(6); # must be no-op @@ -776,13 +788,14 @@ $x = $mbf->new("12340"); $x->bfround(2); is($x, "12340", q|$x = "12340"|); -# MBI::bfround should clear A for negative P +note("MBI::bfround should clear A for negative P"); + $x = $mbi->new("1234"); $x->accuracy(3); $x->bfround(-2); is($x->{_a}, undef, q|$x->{_a} = undef|); -# test that bfround() and bround() work with large numbers +note("test that bfround() and bround() work with large numbers"); $x = $mbf->new(1)->bdiv(5678, undef, -63); is($x, "0.000176118351532229658330398027474462839027826699542092286016203", @@ -801,13 +814,15 @@ is($x, "0.00017611835153222965833039802747446283902782" . q|669954209228601620288834096512856639662"|); ############################################################################### -# rounding with already set precision/accuracy + +note("rounding with already set precision/accuracy"); $x = $mbf->new(1); $x->{_p} = -5; is($x, "1.00000", q|$x = "1.00000"|); -# further rounding donw +note("further rounding down"); + is($x->bfround(-2), "1.00", q|$x->bfround(-2) = "1.00"|); is($x->{_p}, -2, q|$x->{_p} = -2|); @@ -821,7 +836,8 @@ $x->{_a} = 5; is($x->bround(2), "1.2", q|$x->bround(2) = "1.2"|); is($x->{_a}, 2, q|$x->{_a} = 2|); -# mantissa/exponent format and A/P +note("mantissa/exponent format and A/P"); + $x = $mbf->new("12345.678"); $x->accuracy(4); is($x, "12350", q|$x = "12350"|); @@ -833,13 +849,14 @@ is($x->{_p}, undef, q|$x->{_p} = undef|); #is($x->{_m}->{_p}, undef, q|$x->{_m}->{_p} = undef|); #is($x->{_e}->{_p}, undef, q|$x->{_e}->{_p} = undef|); -# check for no A/P in case of fallback -# result +note("check for no A/P in case of fallback result"); + $x = $mbf->new(100) / 3; is($x->{_a}, undef, q|$x->{_a} = undef|); is($x->{_p}, undef, q|$x->{_p} = undef|); -# result & remainder +note("result & remainder"); + $x = $mbf->new(100) / 3; ($x, $y) = $x->bdiv(3); is($x->{_a}, undef, q|$x->{_a} = undef|); diff --git a/cpan/Math-BigInt/t/new-mbf.t b/cpan/Math-BigInt/t/new-mbf.t index 547a69ca4b..0400390c35 100644 --- a/cpan/Math-BigInt/t/new-mbf.t +++ b/cpan/Math-BigInt/t/new-mbf.t @@ -3,12 +3,12 @@ use strict; use warnings; -use Test::More tests => 69; +use Test::More tests => 100; my $class; BEGIN { $class = 'Math::BigFloat'; } -BEGIN { use_ok($class, '1.999710'); } +BEGIN { use_ok($class, '1.999821'); } while (<DATA>) { s/#.*$//; # remove comments @@ -45,48 +45,54 @@ infinity:inf -inf:-inf -infinity:-inf -# This is the same data as in from_hex-mbf.t, except that some of them are -# commented out, since new() only treats input as hexadecimal if it has a "0x" -# or "0X" prefix, possibly with a leading "+" or "-" sign. +# This is the same data as in from_bin-mbf.t, except that some of them are +# commented out, since new() only treats input as binary if it has a "0b" or +# "0B" prefix, possibly with a leading "+" or "-" sign. Duplicates from above +# are also commented out. -0x1p+0:1 -0x.8p+1:1 -0x.4p+2:1 -0x.2p+3:1 -0x.1p+4:1 -0x2p-1:1 -0x4p-2:1 -0x8p-3:1 +0b1p+0:1 +0b.1p+1:1 +0b.01p+2:1 +0b.001p+3:1 +0b.0001p+4:1 +0b10p-1:1 +0b100p-2:1 +0b1000p-3:1 --0x1p+0:-1 +-0b1p+0:-1 -0x0p+0:0 -0x0p+7:0 -0x0p-7:0 -0x0.p+0:0 -0x.0p+0:0 -0x0.0p+0:0 +0b0p+0:0 +0b0p+7:0 +0b0p-7:0 +0b0.p+0:0 +0b.0p+0:0 +0b0.0p+0:0 -0xcafe:51966 -#xcafe:51966 -#cafe:51966 +0b1100101011111110:51966 +0B1100101011111110:51966 +b1100101011111110:51966 +B1100101011111110:51966 +#1100101011111110:51966 -0x1.9p+3:12.5 -0x12.34p-1:9.1015625 --0x.789abcdefp+32:-2023406814.9375 -0x12.3456789ap+31:39093746765 +0b1.1001p+3:12.5 +0b10010.001101p-1:9.1015625 +-0b.11110001001101010111100110111101111p+31:-2023406814.9375 +0b10.0100011010001010110011110001001101p+34:39093746765 + +0b.p+0:NaN #NaN:NaN #+inf:NaN #-inf:NaN -0x.p+0:NaN # This is more or less the same data as in from_oct-mbf.t, except that some of -# them are commented out, since new() only treats input as octal if it has a -# "0" prefix and a binary exponent, and possibly a leading "+" or "-" sign. -# Duplicates from above are also commented out. +# them are commented out, since new() does not consider a number with just a +# leading zero to be an octal number. Duplicates from above are also commented +# out. + +# Without "0o" prefix. -01p+0:1 +001p+0:1 00.4p+1:1 00.2p+2:1 00.1p+3:1 @@ -102,7 +108,6 @@ infinity:inf 00p-7:0 00.p+0:0 00.0p+0:0 -#00.0p+0:0 #145376:51966 #0145376:51966 @@ -113,44 +118,80 @@ infinity:inf -00.361152746757p+32:-2023406814.9375 044.3212636115p+30:39093746765 +0.p+0:NaN +.p+0:NaN + +# With "0o" prefix. + +0o01p+0:1 +0o0.4p+1:1 +0o0.2p+2:1 +0o0.1p+3:1 +0o0.04p+4:1 +0o02p-1:1 +0o04p-2:1 +0o010p-3:1 + +-0o1p+0:-1 + +0o0p+0:0 +0o0p+7:0 +0o0p-7:0 +0o0.p+0:0 +0o.0p+0:0 +0o0.0p+0:0 + +0o145376:51966 +0O145376:51966 +o145376:51966 +O145376:51966 + +0o3.1p+2:12.5 +0o22.15p-1:9.1015625 +-0o0.361152746757p+32:-2023406814.9375 +0o44.3212636115p+30:39093746765 + +0o.p+0:NaN + #NaN:NaN #+inf:NaN #-inf:NaN -0.p+0:NaN -# This is the same data as in from_bin-mbf.t, except that some of them are -# commented out, since new() only treats input as binary if it has a "0b" or -# "0B" prefix, possibly with a leading "+" or "-" sign. Duplicates from above -# are also commented out. +# This is the same data as in from_hex-mbf.t, except that some of them are +# commented out, since new() only treats input as hexadecimal if it has a "0x" +# or "0X" prefix, possibly with a leading "+" or "-" sign. -0b1p+0:1 -0b.1p+1:1 -0b.01p+2:1 -0b.001p+3:1 -0b.0001p+4:1 -0b10p-1:1 -0b100p-2:1 -0b1000p-3:1 +0x1p+0:1 +0x.8p+1:1 +0x.4p+2:1 +0x.2p+3:1 +0x.1p+4:1 +0x2p-1:1 +0x4p-2:1 +0x8p-3:1 --0b1p+0:-1 +-0x1p+0:-1 -0b0p+0:0 -0b0p+7:0 -0b0p-7:0 -0b0.p+0:0 -0b.0p+0:0 -0b0.0p+0:0 +0x0p+0:0 +0x0p+7:0 +0x0p-7:0 +0x0.p+0:0 +0x.0p+0:0 +0x0.0p+0:0 -0b1100101011111110:51966 -#b1100101011111110:51966 -#1100101011111110:51966 +0xcafe:51966 +0Xcafe:51966 +xcafe:51966 +Xcafe:51966 +#cafe:51966 -0b1.1001p+3:12.5 -0b10010.001101p-1:9.1015625 --0b.11110001001101010111100110111101111p+31:-2023406814.9375 -0b10.0100011010001010110011110001001101p+34:39093746765 +0x1.9p+3:12.5 +0x12.34p-1:9.1015625 +-0x.789abcdefp+32:-2023406814.9375 +0x12.3456789ap+31:39093746765 + +0x.p+0:NaN #NaN:NaN #+inf:NaN #-inf:NaN -0b.p+0:NaN diff --git a/cpan/Math-BigInt/t/sparts-mbf.t b/cpan/Math-BigInt/t/sparts-mbf.t index ac8cc761e7..1e16763b8a 100644 --- a/cpan/Math-BigInt/t/sparts-mbf.t +++ b/cpan/Math-BigInt/t/sparts-mbf.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 1840; +use Test::More tests => 1848; use Math::BigFloat; @@ -44,6 +44,37 @@ while (<DATA>) { } +# Verify that the accuracy of the significand and the exponent depends on the +# accuracy of the invocand, if set, not the class. + +note(qq|\nVerify that accuracy depends on invocand, not class.\n\n|); + +{ + Math::BigFloat -> accuracy(20); + my $x = Math::BigFloat -> new("3"); # accuray is 20 + $x -> accuracy(10); # reduce accuray to 10 + + my ($mant, $expo) = $x -> sparts(); + cmp_ok($mant, '==', 3, "value of significand"); + cmp_ok($expo, '==', 0, "value of exponent"); + cmp_ok($mant -> accuracy(), '==', 10, "accuracy of significand"); + cmp_ok($expo -> accuracy(), '==', 20, "accuracy of exponent"); +} + +note(qq|\nVerify that precision depends on invocand, not class.\n\n|); + +{ + Math::BigFloat -> precision(20); + my $x = Math::BigFloat -> new("3"); # precision is 20 + $x -> precision(10); # reduce precision to 10 + + my ($mant, $expo) = $x -> sparts(); + cmp_ok($mant, '==', 3, "value of significand"); + cmp_ok($expo, '==', 0, "value of exponent"); + cmp_ok($mant -> precision(), '==', 10, "precision of significand"); + cmp_ok($expo -> precision(), '==', 20, "precision of exponent"); +} + __DATA__ NaN:NaN:NaN diff --git a/cpan/Math-BigInt/t/sparts-mbi.t b/cpan/Math-BigInt/t/sparts-mbi.t index 648de7e828..86620b7faf 100644 --- a/cpan/Math-BigInt/t/sparts-mbi.t +++ b/cpan/Math-BigInt/t/sparts-mbi.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 784; +use Test::More tests => 792; use Math::BigInt; @@ -44,6 +44,37 @@ while (<DATA>) { } +# Verify that the accuracy of the significand and the exponent depends on the +# accuracy of the invocand, if set, not the class. + +note(qq|\nVerify that accuracy depends on invocand, not class.\n\n|); + +{ + Math::BigInt -> accuracy(20); + my $x = Math::BigInt -> new("3"); # accuracy is 20 + $x -> accuracy(10); # reduce accuracy to 10 + + my ($mant, $expo) = $x -> sparts(); + cmp_ok($mant, '==', 3, "value of significand"); + cmp_ok($expo, '==', 0, "value of exponent"); + cmp_ok($mant -> accuracy(), '==', 10, "accuracy of significand"); + cmp_ok($expo -> accuracy(), '==', 20, "accuracy of exponent"); +} + +note(qq|\nVerify that precision depends on invocand, not class.\n\n|); + +{ + Math::BigInt -> precision(20); + my $x = Math::BigInt -> new("3"); # precision is 20 + $x -> precision(10); # reduce precision to 10 + + my ($mant, $expo) = $x -> sparts(); + cmp_ok($mant, '==', 3, "value of significand"); + cmp_ok($expo, '==', 0, "value of exponent"); + cmp_ok($mant -> precision(), '==', 10, "precision of significand"); + cmp_ok($expo -> precision(), '==', 20, "precision of exponent"); +} + __DATA__ NaN:NaN:NaN diff --git a/cpan/Math-BigInt/t/sub_mbf.t b/cpan/Math-BigInt/t/sub_mbf.t index 2f5d3fc1e7..472ad9445e 100644 --- a/cpan/Math-BigInt/t/sub_mbf.t +++ b/cpan/Math-BigInt/t/sub_mbf.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 2830 # tests in require'd file +use Test::More tests => 3076 # tests in require'd file + 6; # tests in this file use lib 't'; diff --git a/cpan/Math-BigInt/t/sub_mbi.t b/cpan/Math-BigInt/t/sub_mbi.t index 97bcdee397..65ea327a5a 100644 --- a/cpan/Math-BigInt/t/sub_mbi.t +++ b/cpan/Math-BigInt/t/sub_mbi.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 4038 # tests in require'd file +use Test::More tests => 4292 # tests in require'd file + 5; # tests in this file use lib 't'; diff --git a/cpan/Math-BigInt/t/to_base-mbi.t b/cpan/Math-BigInt/t/to_base-mbi.t index 6ffee61896..c97e2887e1 100644 --- a/cpan/Math-BigInt/t/to_base-mbi.t +++ b/cpan/Math-BigInt/t/to_base-mbi.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 24; +use Test::More tests => 30; my $class; @@ -43,6 +43,13 @@ __END__ # Base 2 +0:2:0 +1:2:1 +2:2:10 +0:2:ab:a +1:2:ab:b +2:2:ab:ba + 250:2:11111010 250:2:01:11111010 diff --git a/cpan/Math-BigInt/t/to_base_num-mbi.t b/cpan/Math-BigInt/t/to_base_num-mbi.t new file mode 100644 index 0000000000..4c66b91ed2 --- /dev/null +++ b/cpan/Math-BigInt/t/to_base_num-mbi.t @@ -0,0 +1,63 @@ +#!perl + +use strict; +use warnings; + +use Test::More tests => 14; + +my $class; + +BEGIN { $class = 'Math::BigInt'; } +BEGIN { use_ok($class); } + +# For simplicity, we use the same data in the test programs for to_base_num() and +# from_base_num(). + +my @data = + ( + [ 0, 2, [ 0 ] ], + [ 1, 2, [ 1 ] ], + [ 2, 2, [ 1, 0 ] ], + [ 3, 2, [ 1, 1, ] ], + [ 4, 2, [ 1, 0, 0 ] ], + + [ 0, 10, [ 0 ] ], + [ 1, 10, [ 1 ] ], + [ 12, 10, [ 1, 2 ] ], + [ 123, 10, [ 1, 2, 3 ] ], + [ 1230, 10, [ 1, 2, 3, 0 ] ], + + [ "123456789", 100, [ 1, 23, 45, 67, 89 ] ], + + [ "1234567890" x 3, + "987654321", + [ "128", "142745769", "763888804", "574845669" ]], + + [ "1234567890" x 5, + "987654321" x 3, + [ "12499999874843750102814", "447551941015330718793208596" ]], + ); + +for (my $i = 0 ; $i <= $#data ; ++ $i) { + my @in = ($data[$i][0], $data[$i][1]); + my $out = $data[$i][2]; + + my ($x, $xo, $y); + my $test = qq|\$x = $class -> new("$in[0]");|; + $test .= qq| \$xo = \$x -> copy();|; + $test .= qq| \$y = \$x -> to_base_num("$in[1]")|; + + eval $test; + die "\nThe following test died when eval()'ed. This indicates a ", + "broken test\n\n $test\n\nThe error message was\n\n $@\n" + if $@; + + subtest $test, sub { + plan tests => 4, + + is($x, $xo, "invocand object was not changed"); + is(ref($y), 'ARRAY', "output arg is an ARRAY ref"); + ok(! grep(ref() ne $class, @$y), "every array element is a $class"); + is_deeply($y, $out, 'every array element has the right value'); + }; +} diff --git a/cpan/Math-BigInt/t/to_ieee754-mbf.t b/cpan/Math-BigInt/t/to_ieee754-mbf.t index 1f043f9ea6..ef79870d0d 100644 --- a/cpan/Math-BigInt/t/to_ieee754-mbf.t +++ b/cpan/Math-BigInt/t/to_ieee754-mbf.t @@ -189,7 +189,7 @@ for my $k (@k) { note("\n", $entry -> {dsc}, " (k = $k): ", $entry -> {asc}, "\n\n"); - my $x = Math::BigFloat -> new($entry -> {mbf}); + my $x = $entry -> {mbf}; my $test = qq|Math::BigFloat -> new("| . stringify($x) . qq|") -> to_ieee754("$format")|; diff --git a/cpan/Math-BigInt/t/upgrade.inc b/cpan/Math-BigInt/t/upgrade.inc index d58376f244..92e85a043b 100644 --- a/cpan/Math-BigInt/t/upgrade.inc +++ b/cpan/Math-BigInt/t/upgrade.inc @@ -91,7 +91,7 @@ while (<DATA>) { } elsif ($f eq "bone") { $try .= " \$x->bone('$args[1]');"; # some unary ops - } elsif ($f =~ /^b(nan|floor|ceil|int|sstr|neg|abs|inc|dec|not|sqrt|d?fac)$/) { + } elsif ($f =~ /^b(nan|floor|ceil|int|sstr|neg|abs|inc|dec|not|sqrt)$/) { $try .= " \$x->$f();"; } elsif ($f eq "length") { $try .= ' $x->length();'; @@ -1291,41 +1291,6 @@ abc:NaN,NaN +inf:inf,inf -inf:-inf,inf -&bfac --1:NaN -NaNfac:NaN -+inf:inf --inf:NaN -0:1 -1:1 -2:2 -3:6 -4:24 -5:120 -6:720 -10:3628800 -11:39916800 -12:479001600 - -&bdfac -NaN:NaN --1:NaN -+inf:inf --inf:NaN -0:1 -1:1 -2:2 -3:3 -4:8 -5:15 -6:48 -7:105 -8:384 -9:945 -10:3840 -11:10395 -12:46080 - &bpow abc:12:NaN 12:abc:NaN diff --git a/cpan/Math-BigInt/t/upgrade.t b/cpan/Math-BigInt/t/upgrade.t index 552c8ae511..b161a8fe2e 100644 --- a/cpan/Math-BigInt/t/upgrade.t +++ b/cpan/Math-BigInt/t/upgrade.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 2208 # tests in require'd file +use Test::More tests => 2146 # tests in require'd file + 2; # tests in this file use Math::BigInt upgrade => 'Math::BigFloat'; diff --git a/cpan/Math-BigInt/t/use_lib1.t b/cpan/Math-BigInt/t/use_lib1.t index c1e4bd98e2..6c80a6af47 100644 --- a/cpan/Math-BigInt/t/use_lib1.t +++ b/cpan/Math-BigInt/t/use_lib1.t @@ -1,15 +1,14 @@ -#!/usr/bin/perl +#!perl # see if using Math::BigInt and Math::BigFloat works together nicely. # all use_lib*.t should be equivalent use strict; use warnings; +use lib 't'; use Test::More tests => 2; -use lib 't'; - use Math::BigFloat lib => 'BareCalc'; is(Math::BigInt->config('lib'), 'Math::BigInt::BareCalc', diff --git a/cpan/Math-BigInt/t/use_lib2.t b/cpan/Math-BigInt/t/use_lib2.t index d5bcff12ad..dc03e1f1e0 100644 --- a/cpan/Math-BigInt/t/use_lib2.t +++ b/cpan/Math-BigInt/t/use_lib2.t @@ -1,15 +1,14 @@ -#!/usr/bin/perl +#!perl # see if using Math::BigInt and Math::BigFloat works together nicely. # all use_lib*.t should be equivalent use strict; use warnings; +use lib 't'; use Test::More tests => 2; -use lib 't'; - use Math::BigInt; use Math::BigFloat lib => 'BareCalc'; diff --git a/cpan/Math-BigInt/t/use_lib3.t b/cpan/Math-BigInt/t/use_lib3.t index f7d801ab85..2dcd72bdcd 100644 --- a/cpan/Math-BigInt/t/use_lib3.t +++ b/cpan/Math-BigInt/t/use_lib3.t @@ -1,15 +1,14 @@ -#!/usr/bin/perl +#!perl # see if using Math::BigInt and Math::BigFloat works together nicely. # all use_lib*.t should be equivalent use strict; use warnings; +use lib 't'; use Test::More tests => 2; -use lib 't'; - use Math::BigInt lib => 'BareCalc'; use Math::BigFloat; diff --git a/cpan/Math-BigInt/t/use_lib4.t b/cpan/Math-BigInt/t/use_lib4.t index 032b425893..d5739c3776 100644 --- a/cpan/Math-BigInt/t/use_lib4.t +++ b/cpan/Math-BigInt/t/use_lib4.t @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!perl # see if using Math::BigInt and Math::BigFloat works together nicely. # all use_lib*.t should be equivalent, except this, since the later overrides diff --git a/cpan/Math-BigInt/t/use_lib5.t b/cpan/Math-BigInt/t/use_lib5.t new file mode 100644 index 0000000000..1c122dd134 --- /dev/null +++ b/cpan/Math-BigInt/t/use_lib5.t @@ -0,0 +1,19 @@ +#!perl + +# see if using Math::BigInt and Math::BigFloat works together nicely. +# all use_lib*.t should be equivalent + +use strict; +use warnings; +use lib 't'; + +use Test::More tests => 2; + +use Math::BigFloat lib => 'BareCalc'; +use Math::BigInt; + +is(Math::BigInt->config('lib'), 'Math::BigInt::BareCalc', + "Math::BigInt->config('lib')"); + +is(Math::BigFloat->new(123)->badd(123), 246, + 'Math::BigFloat->new(123)->badd(123)'); diff --git a/cpan/Math-BigInt/t/use_lib6.t b/cpan/Math-BigInt/t/use_lib6.t new file mode 100644 index 0000000000..7271ca419d --- /dev/null +++ b/cpan/Math-BigInt/t/use_lib6.t @@ -0,0 +1,17 @@ +#!perl + +# see if using Math::BigInt and Math::BigFloat works together nicely. +# all use_lib*.t should be equivalent + +use strict; +use warnings; +use lib 't'; + +use Test::More tests => 1; + +use Math::BigInt lib => 'BareCalc'; +eval "use Math::BigFloat only => 'foobar';"; + +my $regex = "Couldn't load the specified math lib" + . ".*and fallback.*is disallowed"; +like($@, qr/$regex/); diff --git a/cpan/Math-BigInt/t/with_sub.t b/cpan/Math-BigInt/t/with_sub.t index 0ce15d10cb..75af3a3ec0 100644 --- a/cpan/Math-BigInt/t/with_sub.t +++ b/cpan/Math-BigInt/t/with_sub.t @@ -5,7 +5,7 @@ use strict; use warnings; -use Test::More tests => 2830 # tests in require'd file +use Test::More tests => 3076 # tests in require'd file + 1; # tests in this file use Math::BigFloat with => 'Math::BigInt::Subclass', diff --git a/cpan/Math-BigRat/lib/Math/BigRat.pm b/cpan/Math-BigRat/lib/Math/BigRat.pm index e3d172836c..e799abd58b 100644 --- a/cpan/Math-BigRat/lib/Math/BigRat.pm +++ b/cpan/Math-BigRat/lib/Math/BigRat.pm @@ -20,7 +20,7 @@ use Carp qw< carp croak >; use Math::BigFloat 1.999718; -our $VERSION = '0.2614'; +our $VERSION = '0.2617'; our @ISA = qw(Math::BigFloat); @@ -366,6 +366,11 @@ sub new { # At this point, neither $n nor $d is a NaN or a zero. + # Copy them now before manipulating them. + + $n = $n -> copy(); + $d = $d -> copy(); + if ($d < 0) { # make sure denominator is positive $n -> bneg(); $d -> bneg(); @@ -1244,7 +1249,7 @@ sub bfloor { } sub bint { - my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_); + my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_); return $x if ($x->{sign} !~ /^[+-]$/ || # +/-inf or NaN $LIB -> _is_one($x->{_d})); # already an integer @@ -1513,13 +1518,18 @@ sub bnok { ($class, $x, $y, @r) = objectify(2, @_); } - my $xint = Math::BigInt -> new($x -> bint() -> bsstr()); - my $yint = Math::BigInt -> new($y -> bint() -> bsstr()); + return $x->bnan() if $x->is_nan() || $y->is_nan(); + return $x->bnan() if (($x->is_finite() && !$x->is_int()) || + ($y->is_finite() && !$y->is_int())); + + my $xint = Math::BigInt -> new($x -> bstr()); + my $yint = Math::BigInt -> new($y -> bstr()); $xint -> bnok($yint); + my $xrat = Math::BigRat -> new($xint); - $x -> {sign} = $xint -> {sign}; - $x -> {_n} = $xint -> {_n}; - $x -> {_d} = $xint -> {_d}; + $x -> {sign} = $xrat -> {sign}; + $x -> {_n} = $xrat -> {_n}; + $x -> {_d} = $xrat -> {_d}; return $x; } @@ -1570,7 +1580,7 @@ sub bmodpow { my $yint = Math::BigInt -> new($y -> copy() -> bint()); my $mint = Math::BigInt -> new($m -> copy() -> bint()); - $xint -> bmodpow($y, $m, @r); + $xint -> bmodpow($yint, $mint, @r); my $xtmp = Math::BigRat -> new($xint -> bsstr()); $x -> {sign} = $xtmp -> {sign}; @@ -1592,7 +1602,7 @@ sub bmodinv { my $xint = Math::BigInt -> new($x -> copy() -> bint()); my $yint = Math::BigInt -> new($y -> copy() -> bint()); - $xint -> bmodinv($y, @r); + $xint -> bmodinv($yint, @r); my $xtmp = Math::BigRat -> new($xint -> bsstr()); $x -> {sign} = $xtmp -> {sign}; @@ -1651,7 +1661,7 @@ sub bsqrt { } sub blsft { - my ($class, $x, $y, $b, @r) = objectify(2, @_); + my ($class, $x, $y, $b) = objectify(2, @_); $b = 2 if !defined $b; $b = $class -> new($b) unless ref($b) && $b -> isa($class); @@ -1665,7 +1675,7 @@ sub blsft { } sub brsft { - my ($class, $x, $y, $b, @r) = objectify(2, @_); + my ($class, $x, $y, $b) = objectify(2, @_); $b = 2 if !defined $b; $b = $class -> new($b) unless ref($b) && $b -> isa($class); @@ -1864,7 +1874,7 @@ sub bacmp { sub beq { my $self = shift; my $selfref = ref $self; - my $class = $selfref || $self; + #my $class = $selfref || $self; croak 'beq() is an instance method, not a class method' unless $selfref; croak 'Wrong number of arguments for beq()' unless @_ == 1; @@ -1876,7 +1886,7 @@ sub beq { sub bne { my $self = shift; my $selfref = ref $self; - my $class = $selfref || $self; + #my $class = $selfref || $self; croak 'bne() is an instance method, not a class method' unless $selfref; croak 'Wrong number of arguments for bne()' unless @_ == 1; @@ -1888,7 +1898,7 @@ sub bne { sub blt { my $self = shift; my $selfref = ref $self; - my $class = $selfref || $self; + #my $class = $selfref || $self; croak 'blt() is an instance method, not a class method' unless $selfref; croak 'Wrong number of arguments for blt()' unless @_ == 1; @@ -1900,7 +1910,7 @@ sub blt { sub ble { my $self = shift; my $selfref = ref $self; - my $class = $selfref || $self; + #my $class = $selfref || $self; croak 'ble() is an instance method, not a class method' unless $selfref; croak 'Wrong number of arguments for ble()' unless @_ == 1; @@ -1912,7 +1922,7 @@ sub ble { sub bgt { my $self = shift; my $selfref = ref $self; - my $class = $selfref || $self; + #my $class = $selfref || $self; croak 'bgt() is an instance method, not a class method' unless $selfref; croak 'Wrong number of arguments for bgt()' unless @_ == 1; @@ -1924,7 +1934,7 @@ sub bgt { sub bge { my $self = shift; my $selfref = ref $self; - my $class = $selfref || $self; + #my $class = $selfref || $self; croak 'bge() is an instance method, not a class method' unless $selfref; @@ -2043,57 +2053,57 @@ sub from_oct { sub import { my $class = shift; - my $l = scalar @_; - my $lib = ''; my @a; + my @a; + my $lib = ''; my $try = 'try'; - for (my $i = 0; $i < $l ; $i++) { + for (my $i = 0; $i <= $#_ ; $i++) { + croak "Error in import(): argument with index $i is undefined" + unless defined($_[$i]); + if ($_[$i] eq ':constant') { # this rest causes overlord er load to step in overload::constant float => sub { $class->new(shift); }; } - # elsif ($_[$i] eq 'upgrade') - # { - # # this causes upgrading - # $upgrade = $_[$i+1]; # or undef to disable - # $i++; - # } + + #elsif ($_[$i] eq 'upgrade') { + # # this causes upgrading + # $upgrade = $_[$i+1]; # or undef to disable + # $i++; + #} + elsif ($_[$i] eq 'downgrade') { # this causes downgrading - $downgrade = $_[$i+1]; # or undef to disable + $downgrade = $_[$i+1]; # or undef to disable $i++; - } elsif ($_[$i] =~ /^(lib|try|only)\z/) { - $lib = $_[$i+1] || ''; # default Calc - $try = $1; # lib, try or only + } + + elsif ($_[$i] =~ /^(lib|try|only)\z/) { + $lib = $_[$i+1] || ''; + $try = $1; # "lib", "try" or "only" $i++; - } elsif ($_[$i] eq 'with') { + } + + elsif ($_[$i] eq 'with') { # this argument is no longer used - #$LIB = $_[$i+1] || 'Math::BigInt::Calc'; # default Math::BigInt::Calc + # $LIB = $_[$i+1] || 'Calc'; + # carp "'with' is no longer supported, use 'lib', 'try', or 'only'"; $i++; - } else { - push @a, $_[$i]; } - } - require Math::BigInt; - # let use Math::BigInt lib => 'GMP'; use Math::BigRat; still have GMP - if ($lib ne '') { - my @c = split /\s*,\s*/, $lib; - foreach (@c) { - $_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters + else { + push @a, $_[$i]; } - $lib = join(",", @c); } - my @import = ('objectify'); - push @import, $try => $lib if $lib ne ''; - # LIB already loaded, so feed it our lib arguments - Math::BigInt->import(@import); + require Math::BigInt; - $LIB = Math::BigFloat->config("lib"); + my @import = ('objectify'); + push @import, $try, $lib if $lib ne ''; + Math::BigInt -> import(@import); - # register us with LIB to get notified of future lib changes - Math::BigInt::_register_callback($class, sub { $LIB = $_[0]; }); + # find out which one was actually loaded + $LIB = Math::BigInt -> config("lib"); # any non :constant stuff is handled by Exporter (loaded by parent class) # even if @_ is empty, to give it a chance @@ -2513,7 +2523,7 @@ Subtracts $y from $x and returns the result. In scalar context, divides $x by $y and returns the result. In list context, does floored division (F-division), returning an integer $q and a remainder $r so that $x = $q * $y + $r. The remainer (modulo) is equal to what is returned -by C<$x->bmod($y)>. +by C<< $x->bmod($y) >>. =item bdec() @@ -2714,43 +2724,25 @@ You can also look for information at: =over 4 -=item * RT: CPAN's request tracker - -L<https://rt.cpan.org/Public/Dist/Display.html?Name=Math-BigRat> - -=item * AnnoCPAN: Annotated CPAN documentation +=item * GitHub -L<http://annocpan.org/dist/Math-BigRat> +L<https://github.com/pjacklam/p5-Math-BigRat> -=item * CPAN Ratings +=item * RT: CPAN's request tracker -L<http://cpanratings.perl.org/dist/Math-BigRat> +L<https://rt.cpan.org/Dist/Display.html?Name=Math-BigRat> -=item * Search CPAN +=item * MetaCPAN -L<http://search.cpan.org/dist/Math-BigRat/> +L<https://metacpan.org/release/Math-BigRat> =item * CPAN Testers Matrix L<http://matrix.cpantesters.org/?dist=Math-BigRat> -=item * The Bignum mailing list - -=over 4 - -=item * Post to mailing list - -C<bignum at lists.scsys.co.uk> - -=item * View mailing list - -L<http://lists.scsys.co.uk/pipermail/bignum/> - -=item * Subscribe/Unsubscribe - -L<http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/bignum> +=item * CPAN Ratings -=back +L<https://cpanratings.perl.org/dist/Math-BigRat> =back @@ -2774,7 +2766,7 @@ Tels L<http://bloodgate.com/> 2001-2009. =item * -Maintained by Peter John Acklam <pjacklam@online.no> 2011- +Maintained by Peter John Acklam <pjacklam@gmail.com> 2011- =back diff --git a/cpan/Math-BigRat/t/bnok-mbr.t b/cpan/Math-BigRat/t/bnok-mbr.t new file mode 100644 index 0000000000..2328297497 --- /dev/null +++ b/cpan/Math-BigRat/t/bnok-mbr.t @@ -0,0 +1,1451 @@ +#!perl + +use strict; +use warnings; + +use Test::More tests => 4957; + +my $class; + +BEGIN { + $class = 'Math::BigRat'; + use_ok($class); +} + +while (<DATA>) { + s/#.*$//; # remove comments + s/\s+$//; # remove trailing whitespace + next unless length; # skip empty lines + + my ($nval, $kval, $nokval) = split /:/; + my ($n, $k, $got, @got); + + for my $context_is_scalar (0, 1) { + for my $k_is_scalar (0, 1) { + + my $test = qq|\$n = $class -> new("$nval");|; + + $test .= $k_is_scalar + ? qq| \$k = "$kval";| + : qq| \$k = $class -> new("$kval");|; + + $test .= $context_is_scalar + ? qq| \$got = \$n -> bnok(\$k);| + : qq| \@got = \$n -> bnok(\$k);|; + + my $desc = "bnok() in "; + $desc .= $context_is_scalar ? "scalar context" : "list context"; + $desc .= $k_is_scalar ? " with k as scalar" : " with k as object"; + + subtest $desc, + sub { + plan tests => $context_is_scalar ? 7 : 8; + + eval $test; + is($@, "", "'$test' gives emtpy \$\@"); + + if ($context_is_scalar) { + + # Check output. + + is(ref($got), $class, + "'$test' output arg is a $class"); + + is($got -> bstr(), $nokval, + "'$test' output arg has the right value"); + + } else { + + # Check number of output arguments. + + cmp_ok(scalar @got, '==', 1, + "'$test' gives one output arg"); + + # Check output. + + is(ref($got[0]), $class, + "'$test' output arg is a $class"); + + is($got[0] -> bstr(), $nokval, + "'$test' output arg has the right value"); + } + + # Check the invocand. + + is(ref($n), $class, + "'$test' invocand is still a $class"); + + is($n -> bstr(), $nokval, + "'$test' invocand has the right value"); + + # Check the input argument. + + if ($k_is_scalar) { + + is(ref($k), '', + "'$test' second input arg is still a scalar"); + + is($k, $kval, + "'$test' second input arg is unmodified"); + + } else { + + is(ref($k), $class, + "'$test' second input arg is still a $class"); + + is($k -> bstr(), $kval, + "'$test' second input arg is unmodified"); + } + }; + } + } +} + +__DATA__ + +# n and/or k is NaN + +NaN:NaN:NaN +NaN:0:NaN +NaN:3:NaN +3:NaN:NaN +NaN:-3:NaN +-3:NaN:NaN + +# n = inf + +inf:-inf:NaN +inf:-3:0 +inf:-2:0 +inf:-1:0 +inf:0:1 +inf:1:inf +inf:2:inf +inf:3:inf +inf:inf:NaN + +# n = -inf + +-inf:-inf:NaN +-inf:-3:0 +-inf:-2:0 +-inf:-1:0 +-inf:0:1 +-inf:1:-inf +-inf:2:inf +-inf:3:-inf +-inf:inf:NaN + +# k = inf + +-3:inf:NaN +-2:inf:NaN +-1:inf:NaN +0:inf:NaN +1:inf:NaN +2:inf:NaN +3:inf:NaN + +# k = -inf + +-3:-inf:NaN +-2:-inf:NaN +-1:-inf:NaN +0:-inf:NaN +1:-inf:NaN +2:-inf:NaN +3:-inf:NaN + +# n = -15, k = n - 15 ... n + 15 + +-15:-30:-77558760 +-15:-29:40116600 +-15:-28:-20058300 +-15:-27:9657700 +-15:-26:-4457400 +-15:-25:1961256 +-15:-24:-817190 +-15:-23:319770 +-15:-22:-116280 +-15:-21:38760 +-15:-20:-11628 +-15:-19:3060 +-15:-18:-680 +-15:-17:120 +-15:-16:-15 +-15:-15:1 +-15:-14:0 +-15:-13:0 +-15:-12:0 +-15:-11:0 +-15:-10:0 +-15:-9:0 +-15:-8:0 +-15:-7:0 +-15:-6:0 +-15:-5:0 +-15:-4:0 +-15:-3:0 +-15:-2:0 +-15:-1:0 +-15:0:1 +-15:1:-15 +-15:2:120 +-15:3:-680 +-15:4:3060 +-15:5:-11628 +-15:6:38760 +-15:7:-116280 +-15:8:319770 +-15:9:-817190 +-15:10:1961256 +-15:11:-4457400 +-15:12:9657700 +-15:13:-20058300 +-15:14:40116600 +-15:15:-77558760 + +# n = -14, k = n - 15 ... n + 15 + +-14:-29:-37442160 +-14:-28:20058300 +-14:-27:-10400600 +-14:-26:5200300 +-14:-25:-2496144 +-14:-24:1144066 +-14:-23:-497420 +-14:-22:203490 +-14:-21:-77520 +-14:-20:27132 +-14:-19:-8568 +-14:-18:2380 +-14:-17:-560 +-14:-16:105 +-14:-15:-14 +-14:-14:1 +-14:-13:0 +-14:-12:0 +-14:-11:0 +-14:-10:0 +-14:-9:0 +-14:-8:0 +-14:-7:0 +-14:-6:0 +-14:-5:0 +-14:-4:0 +-14:-3:0 +-14:-2:0 +-14:-1:0 +-14:0:1 +-14:1:-14 +-14:2:105 +-14:3:-560 +-14:4:2380 +-14:5:-8568 +-14:6:27132 +-14:7:-77520 +-14:8:203490 +-14:9:-497420 +-14:10:1144066 +-14:11:-2496144 +-14:12:5200300 +-14:13:-10400600 +-14:14:20058300 +-14:15:-37442160 + +# n = -13, k = n - 15 ... n + 15 + +-13:-28:-17383860 +-13:-27:9657700 +-13:-26:-5200300 +-13:-25:2704156 +-13:-24:-1352078 +-13:-23:646646 +-13:-22:-293930 +-13:-21:125970 +-13:-20:-50388 +-13:-19:18564 +-13:-18:-6188 +-13:-17:1820 +-13:-16:-455 +-13:-15:91 +-13:-14:-13 +-13:-13:1 +-13:-12:0 +-13:-11:0 +-13:-10:0 +-13:-9:0 +-13:-8:0 +-13:-7:0 +-13:-6:0 +-13:-5:0 +-13:-4:0 +-13:-3:0 +-13:-2:0 +-13:-1:0 +-13:0:1 +-13:1:-13 +-13:2:91 +-13:3:-455 +-13:4:1820 +-13:5:-6188 +-13:6:18564 +-13:7:-50388 +-13:8:125970 +-13:9:-293930 +-13:10:646646 +-13:11:-1352078 +-13:12:2704156 +-13:13:-5200300 +-13:14:9657700 +-13:15:-17383860 + +# n = -12, k = n - 15 ... n + 15 + +-12:-27:-7726160 +-12:-26:4457400 +-12:-25:-2496144 +-12:-24:1352078 +-12:-23:-705432 +-12:-22:352716 +-12:-21:-167960 +-12:-20:75582 +-12:-19:-31824 +-12:-18:12376 +-12:-17:-4368 +-12:-16:1365 +-12:-15:-364 +-12:-14:78 +-12:-13:-12 +-12:-12:1 +-12:-11:0 +-12:-10:0 +-12:-9:0 +-12:-8:0 +-12:-7:0 +-12:-6:0 +-12:-5:0 +-12:-4:0 +-12:-3:0 +-12:-2:0 +-12:-1:0 +-12:0:1 +-12:1:-12 +-12:2:78 +-12:3:-364 +-12:4:1365 +-12:5:-4368 +-12:6:12376 +-12:7:-31824 +-12:8:75582 +-12:9:-167960 +-12:10:352716 +-12:11:-705432 +-12:12:1352078 +-12:13:-2496144 +-12:14:4457400 +-12:15:-7726160 + +# n = -11, k = n - 15 ... n + 15 + +-11:-26:-3268760 +-11:-25:1961256 +-11:-24:-1144066 +-11:-23:646646 +-11:-22:-352716 +-11:-21:184756 +-11:-20:-92378 +-11:-19:43758 +-11:-18:-19448 +-11:-17:8008 +-11:-16:-3003 +-11:-15:1001 +-11:-14:-286 +-11:-13:66 +-11:-12:-11 +-11:-11:1 +-11:-10:0 +-11:-9:0 +-11:-8:0 +-11:-7:0 +-11:-6:0 +-11:-5:0 +-11:-4:0 +-11:-3:0 +-11:-2:0 +-11:-1:0 +-11:0:1 +-11:1:-11 +-11:2:66 +-11:3:-286 +-11:4:1001 +-11:5:-3003 +-11:6:8008 +-11:7:-19448 +-11:8:43758 +-11:9:-92378 +-11:10:184756 +-11:11:-352716 +-11:12:646646 +-11:13:-1144066 +-11:14:1961256 +-11:15:-3268760 + +# n = -10, k = n - 15 ... n + 15 + +-10:-25:-1307504 +-10:-24:817190 +-10:-23:-497420 +-10:-22:293930 +-10:-21:-167960 +-10:-20:92378 +-10:-19:-48620 +-10:-18:24310 +-10:-17:-11440 +-10:-16:5005 +-10:-15:-2002 +-10:-14:715 +-10:-13:-220 +-10:-12:55 +-10:-11:-10 +-10:-10:1 +-10:-9:0 +-10:-8:0 +-10:-7:0 +-10:-6:0 +-10:-5:0 +-10:-4:0 +-10:-3:0 +-10:-2:0 +-10:-1:0 +-10:0:1 +-10:1:-10 +-10:2:55 +-10:3:-220 +-10:4:715 +-10:5:-2002 +-10:6:5005 +-10:7:-11440 +-10:8:24310 +-10:9:-48620 +-10:10:92378 +-10:11:-167960 +-10:12:293930 +-10:13:-497420 +-10:14:817190 +-10:15:-1307504 + +# n = -9, k = n - 15 ... n + 15 + +-9:-24:-490314 +-9:-23:319770 +-9:-22:-203490 +-9:-21:125970 +-9:-20:-75582 +-9:-19:43758 +-9:-18:-24310 +-9:-17:12870 +-9:-16:-6435 +-9:-15:3003 +-9:-14:-1287 +-9:-13:495 +-9:-12:-165 +-9:-11:45 +-9:-10:-9 +-9:-9:1 +-9:-8:0 +-9:-7:0 +-9:-6:0 +-9:-5:0 +-9:-4:0 +-9:-3:0 +-9:-2:0 +-9:-1:0 +-9:0:1 +-9:1:-9 +-9:2:45 +-9:3:-165 +-9:4:495 +-9:5:-1287 +-9:6:3003 +-9:7:-6435 +-9:8:12870 +-9:9:-24310 +-9:10:43758 +-9:11:-75582 +-9:12:125970 +-9:13:-203490 +-9:14:319770 +-9:15:-490314 + +# n = -8, k = n - 15 ... n + 15 + +-8:-23:-170544 +-8:-22:116280 +-8:-21:-77520 +-8:-20:50388 +-8:-19:-31824 +-8:-18:19448 +-8:-17:-11440 +-8:-16:6435 +-8:-15:-3432 +-8:-14:1716 +-8:-13:-792 +-8:-12:330 +-8:-11:-120 +-8:-10:36 +-8:-9:-8 +-8:-8:1 +-8:-7:0 +-8:-6:0 +-8:-5:0 +-8:-4:0 +-8:-3:0 +-8:-2:0 +-8:-1:0 +-8:0:1 +-8:1:-8 +-8:2:36 +-8:3:-120 +-8:4:330 +-8:5:-792 +-8:6:1716 +-8:7:-3432 +-8:8:6435 +-8:9:-11440 +-8:10:19448 +-8:11:-31824 +-8:12:50388 +-8:13:-77520 +-8:14:116280 +-8:15:-170544 + +# n = -7, k = n - 15 ... n + 15 + +-7:-22:-54264 +-7:-21:38760 +-7:-20:-27132 +-7:-19:18564 +-7:-18:-12376 +-7:-17:8008 +-7:-16:-5005 +-7:-15:3003 +-7:-14:-1716 +-7:-13:924 +-7:-12:-462 +-7:-11:210 +-7:-10:-84 +-7:-9:28 +-7:-8:-7 +-7:-7:1 +-7:-6:0 +-7:-5:0 +-7:-4:0 +-7:-3:0 +-7:-2:0 +-7:-1:0 +-7:0:1 +-7:1:-7 +-7:2:28 +-7:3:-84 +-7:4:210 +-7:5:-462 +-7:6:924 +-7:7:-1716 +-7:8:3003 +-7:9:-5005 +-7:10:8008 +-7:11:-12376 +-7:12:18564 +-7:13:-27132 +-7:14:38760 +-7:15:-54264 + +# n = -6, k = n - 15 ... n + 15 + +-6:-21:-15504 +-6:-20:11628 +-6:-19:-8568 +-6:-18:6188 +-6:-17:-4368 +-6:-16:3003 +-6:-15:-2002 +-6:-14:1287 +-6:-13:-792 +-6:-12:462 +-6:-11:-252 +-6:-10:126 +-6:-9:-56 +-6:-8:21 +-6:-7:-6 +-6:-6:1 +-6:-5:0 +-6:-4:0 +-6:-3:0 +-6:-2:0 +-6:-1:0 +-6:0:1 +-6:1:-6 +-6:2:21 +-6:3:-56 +-6:4:126 +-6:5:-252 +-6:6:462 +-6:7:-792 +-6:8:1287 +-6:9:-2002 +-6:10:3003 +-6:11:-4368 +-6:12:6188 +-6:13:-8568 +-6:14:11628 +-6:15:-15504 + +# n = -5, k = n - 15 ... n + 15 + +-5:-20:-3876 +-5:-19:3060 +-5:-18:-2380 +-5:-17:1820 +-5:-16:-1365 +-5:-15:1001 +-5:-14:-715 +-5:-13:495 +-5:-12:-330 +-5:-11:210 +-5:-10:-126 +-5:-9:70 +-5:-8:-35 +-5:-7:15 +-5:-6:-5 +-5:-5:1 +-5:-4:0 +-5:-3:0 +-5:-2:0 +-5:-1:0 +-5:0:1 +-5:1:-5 +-5:2:15 +-5:3:-35 +-5:4:70 +-5:5:-126 +-5:6:210 +-5:7:-330 +-5:8:495 +-5:9:-715 +-5:10:1001 +-5:11:-1365 +-5:12:1820 +-5:13:-2380 +-5:14:3060 +-5:15:-3876 + +# n = -4, k = n - 15 ... n + 15 + +-4:-19:-816 +-4:-18:680 +-4:-17:-560 +-4:-16:455 +-4:-15:-364 +-4:-14:286 +-4:-13:-220 +-4:-12:165 +-4:-11:-120 +-4:-10:84 +-4:-9:-56 +-4:-8:35 +-4:-7:-20 +-4:-6:10 +-4:-5:-4 +-4:-4:1 +-4:-3:0 +-4:-2:0 +-4:-1:0 +-4:0:1 +-4:1:-4 +-4:2:10 +-4:3:-20 +-4:4:35 +-4:5:-56 +-4:6:84 +-4:7:-120 +-4:8:165 +-4:9:-220 +-4:10:286 +-4:11:-364 +-4:12:455 +-4:13:-560 +-4:14:680 +-4:15:-816 + +# n = -3, k = n - 15 ... n + 15 + +-3:-18:-136 +-3:-17:120 +-3:-16:-105 +-3:-15:91 +-3:-14:-78 +-3:-13:66 +-3:-12:-55 +-3:-11:45 +-3:-10:-36 +-3:-9:28 +-3:-8:-21 +-3:-7:15 +-3:-6:-10 +-3:-5:6 +-3:-4:-3 +-3:-3:1 +-3:-2:0 +-3:-1:0 +-3:0:1 +-3:1:-3 +-3:2:6 +-3:3:-10 +-3:4:15 +-3:5:-21 +-3:6:28 +-3:7:-36 +-3:8:45 +-3:9:-55 +-3:10:66 +-3:11:-78 +-3:12:91 +-3:13:-105 +-3:14:120 +-3:15:-136 + +# n = -2, k = n - 15 ... n + 15 + +-2:-17:-16 +-2:-16:15 +-2:-15:-14 +-2:-14:13 +-2:-13:-12 +-2:-12:11 +-2:-11:-10 +-2:-10:9 +-2:-9:-8 +-2:-8:7 +-2:-7:-6 +-2:-6:5 +-2:-5:-4 +-2:-4:3 +-2:-3:-2 +-2:-2:1 +-2:-1:0 +-2:0:1 +-2:1:-2 +-2:2:3 +-2:3:-4 +-2:4:5 +-2:5:-6 +-2:6:7 +-2:7:-8 +-2:8:9 +-2:9:-10 +-2:10:11 +-2:11:-12 +-2:12:13 +-2:13:-14 +-2:14:15 +-2:15:-16 + +# n = -1, k = n - 15 ... n + 15 + +-1:-16:-1 +-1:-15:1 +-1:-14:-1 +-1:-13:1 +-1:-12:-1 +-1:-11:1 +-1:-10:-1 +-1:-9:1 +-1:-8:-1 +-1:-7:1 +-1:-6:-1 +-1:-5:1 +-1:-4:-1 +-1:-3:1 +-1:-2:-1 +-1:-1:1 +-1:0:1 +-1:1:-1 +-1:2:1 +-1:3:-1 +-1:4:1 +-1:5:-1 +-1:6:1 +-1:7:-1 +-1:8:1 +-1:9:-1 +-1:10:1 +-1:11:-1 +-1:12:1 +-1:13:-1 +-1:14:1 +-1:15:-1 + +# n = 0, k = n - 15 ... n + 15 + +0:-15:0 +0:-14:0 +0:-13:0 +0:-12:0 +0:-11:0 +0:-10:0 +0:-9:0 +0:-8:0 +0:-7:0 +0:-6:0 +0:-5:0 +0:-4:0 +0:-3:0 +0:-2:0 +0:-1:0 +0:0:1 +0:1:0 +0:2:0 +0:3:0 +0:4:0 +0:5:0 +0:6:0 +0:7:0 +0:8:0 +0:9:0 +0:10:0 +0:11:0 +0:12:0 +0:13:0 +0:14:0 +0:15:0 + +# n = 1, k = n - 15 ... n + 15 + +1:-15:0 +1:-14:0 +1:-13:0 +1:-12:0 +1:-11:0 +1:-10:0 +1:-9:0 +1:-8:0 +1:-7:0 +1:-6:0 +1:-5:0 +1:-4:0 +1:-3:0 +1:-2:0 +1:-1:0 +1:0:1 +1:1:1 +1:2:0 +1:3:0 +1:4:0 +1:5:0 +1:6:0 +1:7:0 +1:8:0 +1:9:0 +1:10:0 +1:11:0 +1:12:0 +1:13:0 +1:14:0 +1:15:0 +1:16:0 + +# n = 2, k = n - 15 ... n + 15 + +2:-15:0 +2:-14:0 +2:-13:0 +2:-12:0 +2:-11:0 +2:-10:0 +2:-9:0 +2:-8:0 +2:-7:0 +2:-6:0 +2:-5:0 +2:-4:0 +2:-3:0 +2:-2:0 +2:-1:0 +2:0:1 +2:1:2 +2:2:1 +2:3:0 +2:4:0 +2:5:0 +2:6:0 +2:7:0 +2:8:0 +2:9:0 +2:10:0 +2:11:0 +2:12:0 +2:13:0 +2:14:0 +2:15:0 +2:16:0 +2:17:0 + +# n = 3, k = n - 15 ... n + 15 + +3:-15:0 +3:-14:0 +3:-13:0 +3:-12:0 +3:-11:0 +3:-10:0 +3:-9:0 +3:-8:0 +3:-7:0 +3:-6:0 +3:-5:0 +3:-4:0 +3:-3:0 +3:-2:0 +3:-1:0 +3:0:1 +3:1:3 +3:2:3 +3:3:1 +3:4:0 +3:5:0 +3:6:0 +3:7:0 +3:8:0 +3:9:0 +3:10:0 +3:11:0 +3:12:0 +3:13:0 +3:14:0 +3:15:0 +3:16:0 +3:17:0 +3:18:0 + +# n = 4, k = n - 15 ... n + 15 + +4:-15:0 +4:-14:0 +4:-13:0 +4:-12:0 +4:-11:0 +4:-10:0 +4:-9:0 +4:-8:0 +4:-7:0 +4:-6:0 +4:-5:0 +4:-4:0 +4:-3:0 +4:-2:0 +4:-1:0 +4:0:1 +4:1:4 +4:2:6 +4:3:4 +4:4:1 +4:5:0 +4:6:0 +4:7:0 +4:8:0 +4:9:0 +4:10:0 +4:11:0 +4:12:0 +4:13:0 +4:14:0 +4:15:0 +4:16:0 +4:17:0 +4:18:0 +4:19:0 + +# n = 5, k = n - 15 ... n + 15 + +5:-15:0 +5:-14:0 +5:-13:0 +5:-12:0 +5:-11:0 +5:-10:0 +5:-9:0 +5:-8:0 +5:-7:0 +5:-6:0 +5:-5:0 +5:-4:0 +5:-3:0 +5:-2:0 +5:-1:0 +5:0:1 +5:1:5 +5:2:10 +5:3:10 +5:4:5 +5:5:1 +5:6:0 +5:7:0 +5:8:0 +5:9:0 +5:10:0 +5:11:0 +5:12:0 +5:13:0 +5:14:0 +5:15:0 +5:16:0 +5:17:0 +5:18:0 +5:19:0 +5:20:0 + +# n = 6, k = n - 15 ... n + 15 + +6:-15:0 +6:-14:0 +6:-13:0 +6:-12:0 +6:-11:0 +6:-10:0 +6:-9:0 +6:-8:0 +6:-7:0 +6:-6:0 +6:-5:0 +6:-4:0 +6:-3:0 +6:-2:0 +6:-1:0 +6:0:1 +6:1:6 +6:2:15 +6:3:20 +6:4:15 +6:5:6 +6:6:1 +6:7:0 +6:8:0 +6:9:0 +6:10:0 +6:11:0 +6:12:0 +6:13:0 +6:14:0 +6:15:0 +6:16:0 +6:17:0 +6:18:0 +6:19:0 +6:20:0 +6:21:0 + +# n = 7, k = n - 15 ... n + 15 + +7:-15:0 +7:-14:0 +7:-13:0 +7:-12:0 +7:-11:0 +7:-10:0 +7:-9:0 +7:-8:0 +7:-7:0 +7:-6:0 +7:-5:0 +7:-4:0 +7:-3:0 +7:-2:0 +7:-1:0 +7:0:1 +7:1:7 +7:2:21 +7:3:35 +7:4:35 +7:5:21 +7:6:7 +7:7:1 +7:8:0 +7:9:0 +7:10:0 +7:11:0 +7:12:0 +7:13:0 +7:14:0 +7:15:0 +7:16:0 +7:17:0 +7:18:0 +7:19:0 +7:20:0 +7:21:0 +7:22:0 + +# n = 8, k = n - 15 ... n + 15 + +8:-15:0 +8:-14:0 +8:-13:0 +8:-12:0 +8:-11:0 +8:-10:0 +8:-9:0 +8:-8:0 +8:-7:0 +8:-6:0 +8:-5:0 +8:-4:0 +8:-3:0 +8:-2:0 +8:-1:0 +8:0:1 +8:1:8 +8:2:28 +8:3:56 +8:4:70 +8:5:56 +8:6:28 +8:7:8 +8:8:1 +8:9:0 +8:10:0 +8:11:0 +8:12:0 +8:13:0 +8:14:0 +8:15:0 +8:16:0 +8:17:0 +8:18:0 +8:19:0 +8:20:0 +8:21:0 +8:22:0 +8:23:0 + +# n = 9, k = n - 15 ... n + 15 + +9:-15:0 +9:-14:0 +9:-13:0 +9:-12:0 +9:-11:0 +9:-10:0 +9:-9:0 +9:-8:0 +9:-7:0 +9:-6:0 +9:-5:0 +9:-4:0 +9:-3:0 +9:-2:0 +9:-1:0 +9:0:1 +9:1:9 +9:2:36 +9:3:84 +9:4:126 +9:5:126 +9:6:84 +9:7:36 +9:8:9 +9:9:1 +9:10:0 +9:11:0 +9:12:0 +9:13:0 +9:14:0 +9:15:0 +9:16:0 +9:17:0 +9:18:0 +9:19:0 +9:20:0 +9:21:0 +9:22:0 +9:23:0 +9:24:0 + +# n = 10, k = n - 15 ... n + 15 + +10:-15:0 +10:-14:0 +10:-13:0 +10:-12:0 +10:-11:0 +10:-10:0 +10:-9:0 +10:-8:0 +10:-7:0 +10:-6:0 +10:-5:0 +10:-4:0 +10:-3:0 +10:-2:0 +10:-1:0 +10:0:1 +10:1:10 +10:2:45 +10:3:120 +10:4:210 +10:5:252 +10:6:210 +10:7:120 +10:8:45 +10:9:10 +10:10:1 +10:11:0 +10:12:0 +10:13:0 +10:14:0 +10:15:0 +10:16:0 +10:17:0 +10:18:0 +10:19:0 +10:20:0 +10:21:0 +10:22:0 +10:23:0 +10:24:0 +10:25:0 + +# n = 11, k = n - 15 ... n + 15 + +11:-15:0 +11:-14:0 +11:-13:0 +11:-12:0 +11:-11:0 +11:-10:0 +11:-9:0 +11:-8:0 +11:-7:0 +11:-6:0 +11:-5:0 +11:-4:0 +11:-3:0 +11:-2:0 +11:-1:0 +11:0:1 +11:1:11 +11:2:55 +11:3:165 +11:4:330 +11:5:462 +11:6:462 +11:7:330 +11:8:165 +11:9:55 +11:10:11 +11:11:1 +11:12:0 +11:13:0 +11:14:0 +11:15:0 +11:16:0 +11:17:0 +11:18:0 +11:19:0 +11:20:0 +11:21:0 +11:22:0 +11:23:0 +11:24:0 +11:25:0 +11:26:0 + +# n = 12, k = n - 15 ... n + 15 + +12:-15:0 +12:-14:0 +12:-13:0 +12:-12:0 +12:-11:0 +12:-10:0 +12:-9:0 +12:-8:0 +12:-7:0 +12:-6:0 +12:-5:0 +12:-4:0 +12:-3:0 +12:-2:0 +12:-1:0 +12:0:1 +12:1:12 +12:2:66 +12:3:220 +12:4:495 +12:5:792 +12:6:924 +12:7:792 +12:8:495 +12:9:220 +12:10:66 +12:11:12 +12:12:1 +12:13:0 +12:14:0 +12:15:0 +12:16:0 +12:17:0 +12:18:0 +12:19:0 +12:20:0 +12:21:0 +12:22:0 +12:23:0 +12:24:0 +12:25:0 +12:26:0 +12:27:0 + +# n = 13, k = n - 15 ... n + 15 + +13:-15:0 +13:-14:0 +13:-13:0 +13:-12:0 +13:-11:0 +13:-10:0 +13:-9:0 +13:-8:0 +13:-7:0 +13:-6:0 +13:-5:0 +13:-4:0 +13:-3:0 +13:-2:0 +13:-1:0 +13:0:1 +13:1:13 +13:2:78 +13:3:286 +13:4:715 +13:5:1287 +13:6:1716 +13:7:1716 +13:8:1287 +13:9:715 +13:10:286 +13:11:78 +13:12:13 +13:13:1 +13:14:0 +13:15:0 +13:16:0 +13:17:0 +13:18:0 +13:19:0 +13:20:0 +13:21:0 +13:22:0 +13:23:0 +13:24:0 +13:25:0 +13:26:0 +13:27:0 +13:28:0 + +# n = 14, k = n - 15 ... n + 15 + +14:-15:0 +14:-14:0 +14:-13:0 +14:-12:0 +14:-11:0 +14:-10:0 +14:-9:0 +14:-8:0 +14:-7:0 +14:-6:0 +14:-5:0 +14:-4:0 +14:-3:0 +14:-2:0 +14:-1:0 +14:0:1 +14:1:14 +14:2:91 +14:3:364 +14:4:1001 +14:5:2002 +14:6:3003 +14:7:3432 +14:8:3003 +14:9:2002 +14:10:1001 +14:11:364 +14:12:91 +14:13:14 +14:14:1 +14:15:0 +14:16:0 +14:17:0 +14:18:0 +14:19:0 +14:20:0 +14:21:0 +14:22:0 +14:23:0 +14:24:0 +14:25:0 +14:26:0 +14:27:0 +14:28:0 +14:29:0 + +# n = 15, k = n - 15 ... n + 15 + +15:-15:0 +15:-14:0 +15:-13:0 +15:-12:0 +15:-11:0 +15:-10:0 +15:-9:0 +15:-8:0 +15:-7:0 +15:-6:0 +15:-5:0 +15:-4:0 +15:-3:0 +15:-2:0 +15:-1:0 +15:0:1 +15:1:15 +15:2:105 +15:3:455 +15:4:1365 +15:5:3003 +15:6:5005 +15:7:6435 +15:8:6435 +15:9:5005 +15:10:3003 +15:11:1365 +15:12:455 +15:13:105 +15:14:15 +15:15:1 +15:16:0 +15:17:0 +15:18:0 +15:19:0 +15:20:0 +15:21:0 +15:22:0 +15:23:0 +15:24:0 +15:25:0 +15:26:0 +15:27:0 +15:28:0 +15:29:0 +15:30:0 diff --git a/cpan/Math-BigRat/t/new-mbr.t b/cpan/Math-BigRat/t/new-mbr.t new file mode 100644 index 0000000000..dad99428d1 --- /dev/null +++ b/cpan/Math-BigRat/t/new-mbr.t @@ -0,0 +1,28 @@ +#!perl + +use strict; +use warnings; + +use Test::More tests => 4; +use Math::BigRat; + +use Scalar::Util qw< refaddr >; + +# CPAN RT #132712. + +my $q1 = Math::BigRat -> new("-1/2"); +my ($n, $d) = $q1 -> parts(); + +my $n_orig = $n -> copy(); +my $d_orig = $d -> copy(); +my $q2 = Math::BigRat -> new($n, $d); + +cmp_ok($n, "==", $n_orig, + "The value of the numerator hasn't changed"); +cmp_ok($d, "==", $d_orig, + "The value of the denominator hasn't changed"); + +isnt(refaddr($n), refaddr($n_orig), + "The addresses of the numerators have changed"); +isnt(refaddr($d), refaddr($d_orig), + "The addresses of the denominators have changed"); diff --git a/cpan/bignum/lib/Math/BigFloat/Trace.pm b/cpan/bignum/lib/Math/BigFloat/Trace.pm index 2fc069370a..2ff54e3015 100644 --- a/cpan/bignum/lib/Math/BigFloat/Trace.pm +++ b/cpan/bignum/lib/Math/BigFloat/Trace.pm @@ -13,7 +13,7 @@ our ($accuracy, $precision, $round_mode, $div_scale); our @ISA = qw(Exporter Math::BigFloat); -our $VERSION = '0.51'; +our $VERSION = '0.53'; use overload; # inherit overload from Math::BigFloat diff --git a/cpan/bignum/lib/Math/BigInt/Trace.pm b/cpan/bignum/lib/Math/BigInt/Trace.pm index 5517bedad9..833927c1f4 100644 --- a/cpan/bignum/lib/Math/BigInt/Trace.pm +++ b/cpan/bignum/lib/Math/BigInt/Trace.pm @@ -13,7 +13,7 @@ our ($accuracy, $precision, $round_mode, $div_scale); our @ISA = qw(Exporter Math::BigInt); -our $VERSION = '0.51'; +our $VERSION = '0.53'; use overload; # inherit overload from Math::BigInt diff --git a/cpan/bignum/lib/bigint.pm b/cpan/bignum/lib/bigint.pm index 8d7048b592..060ff4dda4 100644 --- a/cpan/bignum/lib/bigint.pm +++ b/cpan/bignum/lib/bigint.pm @@ -4,7 +4,7 @@ use 5.010; use strict; use warnings; -our $VERSION = '0.51'; +our $VERSION = '0.53'; use Exporter; our @ISA = qw( Exporter ); @@ -122,7 +122,7 @@ sub _hex_core { # Strip off, clean, and parse as much as we can from the beginning. my $x; - if ($str =~ s/ ^ (0?[xX])? ( [0-9a-fA-F]* ( _ [0-9a-fA-F]+ )* ) //x) { + if ($str =~ s/ ^ ( 0? [xX] )? ( [0-9a-fA-F]* ( _ [0-9a-fA-F]+ )* ) //x) { my $chrs = $2; $chrs =~ tr/_//d; $chrs = '0' unless CORE::length $chrs; @@ -162,7 +162,7 @@ sub _oct_core { # Strip off, clean, and parse as much as we can from the beginning. - if ($str =~ s/ ^ (0?[bB])? ( [01]* ( _ [01]+ )* ) //x) { + if ($str =~ s/ ^ ( 0? [bB] )? ( [01]* ( _ [01]+ )* ) //x) { my $chrs = $2; $chrs =~ tr/_//d; $chrs = '0' unless CORE::length $chrs; @@ -183,21 +183,20 @@ sub _oct_core { # Octal input. Strip off, clean, and parse as much as we can from the # beginning. - if ($str =~ s/ ^ ( [0-7]* ( _ [0-7]+ )* ) //x) { - my $chrs = $1; + if ($str =~ s/ ^ ( 0? [oO] )? ( [0-7]* ( _ [0-7]+ )* ) //x) { + my $chrs = $2; $chrs =~ tr/_//d; $chrs = '0' unless CORE::length $chrs; $x = Math::BigInt -> from_oct($chrs); } - # Warn about trailing garbage. CORE::oct() only warns about 8 and 9. + # Warn about trailing garbage. CORE::oct() only warns about 8 and 9, but it + # is more helpful to warn about all invalid digits. if (CORE::length($str)) { - my $chr = substr($str, 0, 1); - if ($chr eq '8' || $chr eq '9') { - require Carp; - Carp::carp(sprintf("Illegal octal digit '%s' ignored", $chr)); - } + require Carp; + Carp::carp(sprintf("Illegal octal digit '%s' ignored", + substr($str, 0, 1))); } return $x; @@ -384,23 +383,23 @@ bigint - Transparent BigInteger support for Perl =head1 SYNOPSIS - use bigint; + use bigint; - $x = 2 + 4.5,"\n"; # BigInt 6 - print 2 ** 512,"\n"; # really is what you think it is - print inf + 42,"\n"; # inf - print NaN * 7,"\n"; # NaN - print hex("0x1234567890123490"),"\n"; # Perl v5.10.0 or later + $x = 2 + 4.5,"\n"; # BigInt 6 + print 2 ** 512,"\n"; # really is what you think it is + print inf + 42,"\n"; # inf + print NaN * 7,"\n"; # NaN + print hex("0x1234567890123490"),"\n"; # Perl v5.10.0 or later - { - no bigint; - print 2 ** 256,"\n"; # a normal Perl scalar now - } + { + no bigint; + print 2 ** 256,"\n"; # a normal Perl scalar now + } - # Import into current package: - use bigint qw/hex oct/; - print hex("0x1234567890123490"),"\n"; - print oct("01234567890123490"),"\n"; + # Import into current package: + use bigint qw/hex oct/; + print hex("0x1234567890123490"),"\n"; + print oct("01234567890123490"),"\n"; =head1 DESCRIPTION @@ -419,23 +418,23 @@ There is one small difference between C<use integer> and C<use bigint>: the former will not affect assignments to variables and the return value of some functions. C<bigint> truncates these results to integer too: - # perl -Minteger -wle 'print 3.2' - 3.2 - # perl -Minteger -wle 'print 3.2 + 0' - 3 - # perl -Mbigint -wle 'print 3.2' - 3 - # perl -Mbigint -wle 'print 3.2 + 0' - 3 - - # perl -Mbigint -wle 'print exp(1) + 0' - 2 - # perl -Mbigint -wle 'print exp(1)' - 2 - # perl -Minteger -wle 'print exp(1)' - 2.71828182845905 - # perl -Minteger -wle 'print exp(1) + 0' - 2 + # perl -Minteger -wle 'print 3.2' + 3.2 + # perl -Minteger -wle 'print 3.2 + 0' + 3 + # perl -Mbigint -wle 'print 3.2' + 3 + # perl -Mbigint -wle 'print 3.2 + 0' + 3 + + # perl -Mbigint -wle 'print exp(1) + 0' + 2 + # perl -Mbigint -wle 'print exp(1)' + 2 + # perl -Minteger -wle 'print exp(1)' + 2.71828182845905 + # perl -Minteger -wle 'print exp(1) + 0' + 2 In practice this makes seldom a difference as B<parts and results> of expressions will be truncated anyway, but this can, for instance, affect the @@ -459,7 +458,7 @@ The following options exist: This sets the accuracy for all math operations. The argument must be greater than or equal to zero. See Math::BigInt's bround() function for details. - perl -Mbigint=a,2 -le 'print 12345+1' + perl -Mbigint=a,2 -le 'print 12345+1' Note that setting precision and accuracy at the same time is not possible. @@ -473,7 +472,7 @@ integer and are ignore like negative values. See Math::BigInt's bfround() function for details. - perl -Mbignum=p,5 -le 'print 123456789+123' + perl -Mbignum=p,5 -le 'print 123456789+123' Note that setting precision and accuracy at the same time is not possible. @@ -500,14 +499,14 @@ overridden in the current scope whenever the bigint pragma is active. Load a different math lib, see L<Math Library>. - perl -Mbigint=lib,GMP -e 'print 2 ** 512' - perl -Mbigint=try,GMP -e 'print 2 ** 512' - perl -Mbigint=only,GMP -e 'print 2 ** 512' + perl -Mbigint=lib,GMP -e 'print 2 ** 512' + perl -Mbigint=try,GMP -e 'print 2 ** 512' + perl -Mbigint=only,GMP -e 'print 2 ** 512' Currently there is no way to specify more than one library on the command line. This means the following does not work: - perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512' + perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512' This will be hopefully fixed soon ;) @@ -515,7 +514,7 @@ This will be hopefully fixed soon ;) This prints out the name and version of all modules used and then exits. - perl -Mbigint=v + perl -Mbigint=v =back @@ -524,26 +523,26 @@ This prints out the name and version of all modules used and then exits. Math with the numbers is done (by default) by a module called Math::BigInt::Calc. This is equivalent to saying: - use bigint lib => 'Calc'; + use bigint lib => 'Calc'; You can change this by using: - use bignum lib => 'GMP'; + use bignum lib => 'GMP'; The following would first try to find Math::BigInt::Foo, then Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc: - use bigint lib => 'Foo,Math::BigInt::Bar'; + use bigint lib => 'Foo,Math::BigInt::Bar'; Using C<lib> warns if none of the specified libraries can be found and L<Math::BigInt> did fall back to one of the default libraries. To suppress this warning, use C<try> instead: - use bignum try => 'GMP'; + use bignum try => 'GMP'; If you want the code to die instead of falling back, use C<only> instead: - use bignum only => 'GMP'; + use bignum only => 'GMP'; Please see respective module documentation for further details. @@ -578,31 +577,31 @@ notation, though. But a warning is in order. When using the following to make a copy of a number, only a shallow copy will be made. - $x = 9; $y = $x; - $x = $y = 7; + $x = 9; $y = $x; + $x = $y = 7; Using the copy or the original with overloaded math is okay, e.g. the following work: - $x = 9; $y = $x; - print $x + 1, " ", $y,"\n"; # prints 10 9 + $x = 9; $y = $x; + print $x + 1, " ", $y,"\n"; # prints 10 9 but calling any method that modifies the number directly will result in B<both> the original and the copy being destroyed: - $x = 9; $y = $x; - print $x->badd(1), " ", $y,"\n"; # prints 10 10 + $x = 9; $y = $x; + print $x->badd(1), " ", $y,"\n"; # prints 10 10 - $x = 9; $y = $x; - print $x->binc(1), " ", $y,"\n"; # prints 10 10 + $x = 9; $y = $x; + print $x->binc(1), " ", $y,"\n"; # prints 10 10 - $x = 9; $y = $x; - print $x->bmul(2), " ", $y,"\n"; # prints 18 18 + $x = 9; $y = $x; + print $x->bmul(2), " ", $y,"\n"; # prints 18 18 Using methods that do not modify, but test that the contents works: - $x = 9; $y = $x; - $z = 9 if $x->is_zero(); # works fine + $x = 9; $y = $x; + $z = 9 if $x->is_zero(); # works fine See the documentation about the copy constructor and C<=> in overload, as well as the documentation in BigInt for further details. @@ -623,21 +622,21 @@ handle bareword C<NaN> properly. =item e - # perl -Mbigint=e -wle 'print e' + # perl -Mbigint=e -wle 'print e' Returns Euler's number C<e>, aka exp(1). Note that under bigint, this is truncated to an integer, and hence simple '2'. =item PI - # perl -Mbigint=PI -wle 'print PI' + # perl -Mbigint=PI -wle 'print PI' Returns PI. Note that under bigint, this is truncated to an integer, and hence simple '3'. =item bexp() - bexp($power,$accuracy); + bexp($power,$accuracy); Returns Euler's number C<e> raised to the appropriate power, to the wanted accuracy. @@ -646,18 +645,18 @@ Note that under bigint, the result is truncated to an integer. Example: - # perl -Mbigint=bexp -wle 'print bexp(1,80)' + # perl -Mbigint=bexp -wle 'print bexp(1,80)' =item bpi() - bpi($accuracy); + bpi($accuracy); Returns PI to the wanted accuracy. Note that under bigint, this is truncated to an integer, and hence simple '3'. Example: - # perl -Mbigint=bpi -wle 'print bpi(80)' + # perl -Mbigint=bpi -wle 'print bpi(80)' =item upgrade() @@ -666,13 +665,13 @@ C<$Math::BigInt::upgrade>. =item in_effect() - use bigint; + use bigint; - print "in effect\n" if bigint::in_effect; # true - { - no bigint; - print "in effect\n" if bigint::in_effect; # false - } + print "in effect\n" if bigint::in_effect; # true + { + no bigint; + print "in effect\n" if bigint::in_effect; # false + } Returns true or false if C<bigint> is in effect in the current scope. @@ -710,13 +709,13 @@ C<Math::BigInt> objects, use a literal number in the expression: Perl does not allow overloading of ranges, so you can neither safely use ranges with bigint endpoints, nor is the iterator variable a bigint. - use 5.010; - for my $i (12..13) { - for my $j (20..21) { - say $i ** $j; # produces a floating-point number, - # not a big integer - } - } + use 5.010; + for my $i (12..13) { + for my $j (20..21) { + say $i ** $j; # produces a floating-point number, + # not a big integer + } + } =item in_effect() @@ -730,22 +729,22 @@ will not happen unless you specifically ask for it with the two import tags "hex" and "oct" - and then it will be global and cannot be disabled inside a scope with "no bigint": - use bigint qw/hex oct/; + use bigint qw/hex oct/; + print hex("0x1234567890123456"); + { + no bigint; print hex("0x1234567890123456"); - { - no bigint; - print hex("0x1234567890123456"); - } + } The second call to hex() will warn about a non-portable constant. Compare this to: - use bigint; + use bigint; - # will warn only under Perl older than v5.9.4 - print hex("0x1234567890123456"); + # will warn only under Perl older than v5.9.4 + print hex("0x1234567890123456"); =back @@ -757,23 +756,23 @@ the others to do the work. The following modules are currently used by bigint: - Math::BigInt::Lite (for speed, and only if it is loadable) - Math::BigInt + Math::BigInt::Lite (for speed, and only if it is loadable) + Math::BigInt =head1 EXAMPLES Some cool command line examples to impress the Python crowd ;) You might want to compare them to the results under -Mbignum or -Mbigrat: - perl -Mbigint -le 'print sqrt(33)' - perl -Mbigint -le 'print 2*255' - perl -Mbigint -le 'print 4.5+2*255' - perl -Mbigint -le 'print 3/7 + 5/7 + 8/3' - perl -Mbigint -le 'print 123->is_odd()' - perl -Mbigint -le 'print log(2)' - perl -Mbigint -le 'print 2 ** 0.5' - perl -Mbigint=a,65 -le 'print 2 ** 0.2' - perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777' + perl -Mbigint -le 'print sqrt(33)' + perl -Mbigint -le 'print 2*255' + perl -Mbigint -le 'print 4.5+2*255' + perl -Mbigint -le 'print 3/7 + 5/7 + 8/3' + perl -Mbigint -le 'print 123->is_odd()' + perl -Mbigint -le 'print log(2)' + perl -Mbigint -le 'print 2 ** 0.5' + perl -Mbigint=a,65 -le 'print 2 ** 0.2' + perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777' =head1 BUGS @@ -815,7 +814,7 @@ L<Math::BigInt::FastCalc>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>. =item * -Maintained by Peter John Acklam E<lt>pjacklam@gmail.com<gt>, 2014-. +Maintained by Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2014-. =back diff --git a/cpan/bignum/lib/bignum.pm b/cpan/bignum/lib/bignum.pm index 55300c8273..fb390fc6a0 100644 --- a/cpan/bignum/lib/bignum.pm +++ b/cpan/bignum/lib/bignum.pm @@ -4,7 +4,7 @@ use 5.010; use strict; use warnings; -our $VERSION = '0.51'; +our $VERSION = '0.53'; use Exporter; our @ISA = qw( bigint ); @@ -230,22 +230,22 @@ bignum - Transparent BigNumber support for Perl =head1 SYNOPSIS - use bignum; + use bignum; - $x = 2 + 4.5,"\n"; # BigFloat 6.5 - print 2 ** 512 * 0.1,"\n"; # really is what you think it is - print inf * inf,"\n"; # prints inf - print NaN * 3,"\n"; # prints NaN + $x = 2 + 4.5,"\n"; # BigFloat 6.5 + print 2 ** 512 * 0.1,"\n"; # really is what you think it is + print inf * inf,"\n"; # prints inf + print NaN * 3,"\n"; # prints NaN - { - no bignum; - print 2 ** 256,"\n"; # a normal Perl scalar now - } + { + no bignum; + print 2 ** 256,"\n"; # a normal Perl scalar now + } - # for older Perls, import into current package: - use bignum qw/hex oct/; - print hex("0x1234567890123490"),"\n"; - print oct("01234567890123490"),"\n"; + # for older Perls, import into current package: + use bignum qw/hex oct/; + print hex("0x1234567890123490"),"\n"; + print oct("01234567890123490"),"\n"; =head1 DESCRIPTION @@ -255,7 +255,7 @@ respectively. If you do - use bignum; + use bignum; at the top of your script, Math::BigFloat and Math::BigInt will be loaded and any constant number will be converted to an object (Math::BigFloat for @@ -263,20 +263,20 @@ floats like 3.1415 and Math::BigInt for integers like 1234). So, the following line: - $x = 1234; + $x = 1234; creates actually a Math::BigInt and stores a reference to in $x. This happens transparently and behind your back, so to speak. You can see this with the following: - perl -Mbignum -le 'print ref(1234)' + perl -Mbignum -le 'print ref(1234)' Don't worry if it says Math::BigInt::Lite, bignum and friends will use Lite if it is installed since it is faster for some operations. It will be automatically upgraded to BigInt whenever necessary: - perl -Mbignum -le 'print ref(2**255)' + perl -Mbignum -le 'print ref(2**255)' This also means it is a bad idea to check for some specific package, since the actual contents of $x might be something unexpected. Due to the @@ -285,29 +285,29 @@ transparent way of bignum C<ref()> should not be necessary, anyway. Since Math::BigInt and BigFloat also overload the normal math operations, the following line will still work: - perl -Mbignum -le 'print ref(1234+1234)' + perl -Mbignum -le 'print ref(1234+1234)' Since numbers are actually objects, you can call all the usual methods from BigInt/BigFloat on them. This even works to some extent on expressions: - perl -Mbignum -le '$x = 1234; print $x->bdec()' - perl -Mbignum -le 'print 1234->copy()->binc();' - perl -Mbignum -le 'print 1234->copy()->binc->badd(6);' - perl -Mbignum -le 'print +(1234)->copy()->binc()' + perl -Mbignum -le '$x = 1234; print $x->bdec()' + perl -Mbignum -le 'print 1234->copy()->binc();' + perl -Mbignum -le 'print 1234->copy()->binc->badd(6);' + perl -Mbignum -le 'print +(1234)->copy()->binc()' (Note that print doesn't do what you expect if the expression starts with '(' hence the C<+>) You can even chain the operations together as usual: - perl -Mbignum -le 'print 1234->copy()->binc->badd(6);' - 1241 + perl -Mbignum -le 'print 1234->copy()->binc->badd(6);' + 1241 Under bignum (or bigint or bigrat), Perl will "upgrade" the numbers appropriately. This means that: - perl -Mbignum -le 'print 1234+4.5' - 1238.5 + perl -Mbignum -le 'print 1234+4.5' + 1238.5 will work correctly. These mixed cases don't do always work when using Math::BigInt or Math::BigFloat alone, or at least not in the way normal Perl @@ -316,19 +316,19 @@ scalars work. If you do want to work with large integers like under C<use integer;>, try C<use bigint;>: - perl -Mbigint -le 'print 1234.5+4.5' - 1238 + perl -Mbigint -le 'print 1234.5+4.5' + 1238 There is also C<use bigrat;> which gives you big rationals: - perl -Mbigrat -le 'print 1234+4.1' - 12381/10 + perl -Mbigrat -le 'print 1234+4.1' + 12381/10 The entire upgrading/downgrading is still experimental and might not work as you expect or may even have bugs. You might get errors like this: - Can't use an undefined value as an ARRAY reference at - /usr/local/lib/perl5/5.8.0/Math/BigInt/Calc.pm line 864 + Can't use an undefined value as an ARRAY reference at + /usr/local/lib/perl5/5.8.0/Math/BigInt/Calc.pm line 864 This means somewhere a routine got a BigFloat/Lite but expected a BigInt (or vice versa) and the upgrade/downgrad path was missing. This is a bug, please @@ -359,7 +359,7 @@ The following options exist: This sets the accuracy for all math operations. The argument must be greater than or equal to zero. See Math::BigInt's bround() function for details. - perl -Mbignum=a,50 -le 'print sqrt(20)' + perl -Mbignum=a,50 -le 'print sqrt(20)' Note that setting precision and accuracy at the same time is not possible. @@ -370,7 +370,7 @@ integer. Negative values mean a fixed number of digits after the dot, while a positive value rounds to this digit left from the dot. 0 or 1 mean round to integer. See Math::BigInt's bfround() function for details. - perl -Mbignum=p,-50 -le 'print sqrt(20)' + perl -Mbignum=p,-50 -le 'print sqrt(20)' Note that setting precision and accuracy at the same time is not possible. @@ -383,12 +383,12 @@ Math::BigInt/Math::BigFloat. Load a different math lib, see L<Math Library>. - perl -Mbignum=l,GMP -e 'print 2 ** 512' + perl -Mbignum=l,GMP -e 'print 2 ** 512' Currently there is no way to specify more than one library on the command line. This means the following does not work: - perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512' + perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512' This will be hopefully fixed soon ;) @@ -410,7 +410,7 @@ overridden in the current scope whenever the bigint pragma is active. This prints out the name and version of all modules used and then exits. - perl -Mbignum=v + perl -Mbignum=v =back @@ -428,35 +428,35 @@ might morph into a different class than BigFloat. But a warning is in order. When using the following to make a copy of a number, only a shallow copy will be made. - $x = 9; $y = $x; - $x = $y = 7; + $x = 9; $y = $x; + $x = $y = 7; If you want to make a real copy, use the following: - $y = $x->copy(); + $y = $x->copy(); Using the copy or the original with overloaded math is okay, e.g. the following work: - $x = 9; $y = $x; - print $x + 1, " ", $y,"\n"; # prints 10 9 + $x = 9; $y = $x; + print $x + 1, " ", $y,"\n"; # prints 10 9 but calling any method that modifies the number directly will result in B<both> the original and the copy being destroyed: - $x = 9; $y = $x; - print $x->badd(1), " ", $y,"\n"; # prints 10 10 + $x = 9; $y = $x; + print $x->badd(1), " ", $y,"\n"; # prints 10 10 - $x = 9; $y = $x; - print $x->binc(1), " ", $y,"\n"; # prints 10 10 + $x = 9; $y = $x; + print $x->binc(1), " ", $y,"\n"; # prints 10 10 - $x = 9; $y = $x; - print $x->bmul(2), " ", $y,"\n"; # prints 18 18 + $x = 9; $y = $x; + print $x->bmul(2), " ", $y,"\n"; # prints 18 18 Using methods that do not modify, but test the contents works: - $x = 9; $y = $x; - $z = 9 if $x->is_zero(); # works fine + $x = 9; $y = $x; + $z = 9 if $x->is_zero(); # works fine See the documentation about the copy constructor and C<=> in overload, as well as the documentation in BigInt for further details. @@ -475,36 +475,36 @@ handle bareword C<NaN> properly. =item e - # perl -Mbignum=e -wle 'print e' + # perl -Mbignum=e -wle 'print e' Returns Euler's number C<e>, aka exp(1). =item PI() - # perl -Mbignum=PI -wle 'print PI' + # perl -Mbignum=PI -wle 'print PI' Returns PI. =item bexp() - bexp($power,$accuracy); + bexp($power,$accuracy); Returns Euler's number C<e> raised to the appropriate power, to the wanted accuracy. Example: - # perl -Mbignum=bexp -wle 'print bexp(1,80)' + # perl -Mbignum=bexp -wle 'print bexp(1,80)' =item bpi() - bpi($accuracy); + bpi($accuracy); Returns PI to the wanted accuracy. Example: - # perl -Mbignum=bpi -wle 'print bpi(80)' + # perl -Mbignum=bpi -wle 'print bpi(80)' =item upgrade() @@ -513,13 +513,13 @@ C<$Math::BigInt::upgrade>. =item in_effect() - use bignum; + use bignum; - print "in effect\n" if bignum::in_effect; # true - { - no bignum; - print "in effect\n" if bignum::in_effect; # false - } + print "in effect\n" if bignum::in_effect; # true + { + no bignum; + print "in effect\n" if bignum::in_effect; # false + } Returns true or false if C<bignum> is in effect in the current scope. @@ -532,16 +532,16 @@ This method only works on Perl v5.9.4 or later. Math with the numbers is done (by default) by a module called Math::BigInt::Calc. This is equivalent to saying: - use bignum lib => 'Calc'; + use bignum lib => 'Calc'; You can change this by using: - use bignum lib => 'GMP'; + use bignum lib => 'GMP'; The following would first try to find Math::BigInt::Foo, then Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc: - use bignum lib => 'Foo,Math::BigInt::Bar'; + use bignum lib => 'Foo,Math::BigInt::Bar'; Please see respective module documentation for further details. @@ -549,11 +549,11 @@ Using C<lib> warns if none of the specified libraries can be found and L<Math::BigInt> did fall back to one of the default libraries. To suppress this warning, use C<try> instead: - use bignum try => 'GMP'; + use bignum try => 'GMP'; If you want the code to die instead of falling back, use C<only> instead: - use bignum only => 'GMP'; + use bignum only => 'GMP'; =head2 INTERNAL FORMAT @@ -616,22 +616,22 @@ will not happen unless you specifically ask for it with the two import tags "hex" and "oct" - and then it will be global and cannot be disabled inside a scope with "no bigint": - use bigint qw/hex oct/; + use bigint qw/hex oct/; + print hex("0x1234567890123456"); + { + no bigint; print hex("0x1234567890123456"); - { - no bigint; - print hex("0x1234567890123456"); - } + } The second call to hex() will warn about a non-portable constant. Compare this to: - use bigint; + use bigint; - # will warn only under older than v5.9.4 - print hex("0x1234567890123456"); + # will warn only under older than v5.9.4 + print hex("0x1234567890123456"); =back @@ -643,24 +643,24 @@ the others to do the work. The following modules are currently used by bignum: - Math::BigInt::Lite (for speed, and only if it is loadable) - Math::BigInt - Math::BigFloat + Math::BigInt::Lite (for speed, and only if it is loadable) + Math::BigInt + Math::BigFloat =head1 EXAMPLES Some cool command line examples to impress the Python crowd ;) - perl -Mbignum -le 'print sqrt(33)' - perl -Mbignum -le 'print 2*255' - perl -Mbignum -le 'print 4.5+2*255' - perl -Mbignum -le 'print 3/7 + 5/7 + 8/3' - perl -Mbignum -le 'print 123->is_odd()' - perl -Mbignum -le 'print log(2)' - perl -Mbignum -le 'print exp(1)' - perl -Mbignum -le 'print 2 ** 0.5' - perl -Mbignum=a,65 -le 'print 2 ** 0.2' - perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777' + perl -Mbignum -le 'print sqrt(33)' + perl -Mbignum -le 'print 2*255' + perl -Mbignum -le 'print 4.5+2*255' + perl -Mbignum -le 'print 3/7 + 5/7 + 8/3' + perl -Mbignum -le 'print 123->is_odd()' + perl -Mbignum -le 'print log(2)' + perl -Mbignum -le 'print exp(1)' + perl -Mbignum -le 'print 2 ** 0.5' + perl -Mbignum=a,65 -le 'print 2 ** 0.2' + perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777' =head1 BUGS @@ -680,26 +680,26 @@ You can also look for information at: =over 4 -=item * RT: CPAN's request tracker - -L<https://rt.cpan.org/Public/Dist/Display.html?Name=bignum> +=item * GitHub -=item * AnnoCPAN: Annotated CPAN documentation +L<https://github.com/pjacklam/p5-bignum> -L<http://annocpan.org/dist/bignum> - -=item * CPAN Ratings +=item * RT: CPAN's request tracker -L<http://cpanratings.perl.org/dist/bignum> +L<https://rt.cpan.org/Dist/Display.html?Name=bignum> -=item * Search CPAN +=item * MetaCPAN -L<http://search.cpan.org/dist/bignum/> +L<https://metacpan.org/release/bignum> =item * CPAN Testers Matrix L<http://matrix.cpantesters.org/?dist=bignum> +=item * CPAN Ratings + +L<https://cpanratings.perl.org/dist/bignum> + =back =head1 LICENSE @@ -724,7 +724,7 @@ L<Math::BigInt::FastCalc>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>. =item * -Maintained by Peter John Acklam E<lt>pjacklam@gmail.com<gt>, 2014-. +Maintained by Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2014-. =back diff --git a/cpan/bignum/lib/bigrat.pm b/cpan/bignum/lib/bigrat.pm index 0a981471b2..28a341c489 100644 --- a/cpan/bignum/lib/bigrat.pm +++ b/cpan/bignum/lib/bigrat.pm @@ -4,7 +4,7 @@ use 5.010; use strict; use warnings; -our $VERSION = '0.51'; +our $VERSION = '0.53'; use Exporter; our @ISA = qw( bigint ); @@ -224,20 +224,20 @@ bigrat - Transparent BigNumber/BigRational support for Perl =head1 SYNOPSIS - use bigrat; + use bigrat; - print 2 + 4.5,"\n"; # BigFloat 6.5 - print 1/3 + 1/4,"\n"; # produces 7/12 + print 2 + 4.5,"\n"; # BigFloat 6.5 + print 1/3 + 1/4,"\n"; # produces 7/12 - { - no bigrat; - print 1/3,"\n"; # 0.33333... - } + { + no bigrat; + print 1/3,"\n"; # 0.33333... + } - # Import into current package: - use bigrat qw/hex oct/; - print hex("0x1234567890123490"),"\n"; - print oct("01234567890123490"),"\n"; + # Import into current package: + use bigrat qw/hex oct/; + print hex("0x1234567890123490"),"\n"; + print oct("01234567890123490"),"\n"; =head1 DESCRIPTION @@ -256,36 +256,36 @@ the others to do the work. The following modules are currently used by bignum: - Math::BigInt::Lite (for speed, and only if it is loadable) - Math::BigInt - Math::BigFloat - Math::BigRat + Math::BigInt::Lite (for speed, and only if it is loadable) + Math::BigInt + Math::BigFloat + Math::BigRat =head2 Math Library Math with the numbers is done (by default) by a module called Math::BigInt::Calc. This is equivalent to saying: - use bigrat lib => 'Calc'; + use bigrat lib => 'Calc'; You can change this by using: - use bignum lib => 'GMP'; + use bignum lib => 'GMP'; The following would first try to find Math::BigInt::Foo, then Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc: - use bigrat lib => 'Foo,Math::BigInt::Bar'; + use bigrat lib => 'Foo,Math::BigInt::Bar'; Using C<lib> warns if none of the specified libraries can be found and L<Math::BigInt> did fall back to one of the default libraries. To suppress this warning, use C<try> instead: - use bignum try => 'GMP'; + use bignum try => 'GMP'; If you want the code to die instead of falling back, use C<only> instead: - use bignum only => 'GMP'; + use bignum only => 'GMP'; Please see respective module documentation for further details. @@ -319,36 +319,36 @@ handle bareword C<NaN> properly. =item e - # perl -Mbigrat=e -wle 'print e' + # perl -Mbigrat=e -wle 'print e' Returns Euler's number C<e>, aka exp(1). =item PI - # perl -Mbigrat=PI -wle 'print PI' + # perl -Mbigrat=PI -wle 'print PI' Returns PI. =item bexp() - bexp($power,$accuracy); + bexp($power,$accuracy); Returns Euler's number C<e> raised to the appropriate power, to the wanted accuracy. Example: - # perl -Mbigrat=bexp -wle 'print bexp(1,80)' + # perl -Mbigrat=bexp -wle 'print bexp(1,80)' =item bpi() - bpi($accuracy); + bpi($accuracy); Returns PI to the wanted accuracy. Example: - # perl -Mbigrat=bpi -wle 'print bpi(80)' + # perl -Mbigrat=bpi -wle 'print bpi(80)' =item upgrade() @@ -357,13 +357,13 @@ C<$Math::BigInt::upgrade>. =item in_effect() - use bigrat; + use bigrat; - print "in effect\n" if bigrat::in_effect; # true - { - no bigrat; - print "in effect\n" if bigrat::in_effect; # false - } + print "in effect\n" if bigrat::in_effect; # true + { + no bigrat; + print "in effect\n" if bigrat::in_effect; # false + } Returns true or false if C<bigrat> is in effect in the current scope. @@ -380,35 +380,35 @@ Math with the numbers is done (by default) by a module called But a warning is in order. When using the following to make a copy of a number, only a shallow copy will be made. - $x = 9; $y = $x; - $x = $y = 7; + $x = 9; $y = $x; + $x = $y = 7; If you want to make a real copy, use the following: - $y = $x->copy(); + $y = $x->copy(); Using the copy or the original with overloaded math is okay, e.g. the following work: - $x = 9; $y = $x; - print $x + 1, " ", $y,"\n"; # prints 10 9 + $x = 9; $y = $x; + print $x + 1, " ", $y,"\n"; # prints 10 9 but calling any method that modifies the number directly will result in B<both> the original and the copy being destroyed: - $x = 9; $y = $x; - print $x->badd(1), " ", $y,"\n"; # prints 10 10 + $x = 9; $y = $x; + print $x->badd(1), " ", $y,"\n"; # prints 10 10 - $x = 9; $y = $x; - print $x->binc(1), " ", $y,"\n"; # prints 10 10 + $x = 9; $y = $x; + print $x->binc(1), " ", $y,"\n"; # prints 10 10 - $x = 9; $y = $x; - print $x->bmul(2), " ", $y,"\n"; # prints 18 18 + $x = 9; $y = $x; + print $x->bmul(2), " ", $y,"\n"; # prints 18 18 Using methods that do not modify, but testthe contents works: - $x = 9; $y = $x; - $z = 9 if $x->is_zero(); # works fine + $x = 9; $y = $x; + $z = 9 if $x->is_zero(); # works fine See the documentation about the copy constructor and C<=> in overload, as well as the documentation in BigInt for further details. @@ -426,7 +426,7 @@ The following options exist: This sets the accuracy for all math operations. The argument must be greater than or equal to zero. See Math::BigInt's bround() function for details. - perl -Mbigrat=a,50 -le 'print sqrt(20)' + perl -Mbigrat=a,50 -le 'print sqrt(20)' Note that setting precision and accuracy at the same time is not possible. @@ -437,7 +437,7 @@ integer. Negative values mean a fixed number of digits after the dot, while a positive value rounds to this digit left from the dot. 0 or 1 mean round to integer. See Math::BigInt's bfround() function for details. - perl -Mbigrat=p,-50 -le 'print sqrt(20)' + perl -Mbigrat=p,-50 -le 'print sqrt(20)' Note that setting precision and accuracy at the same time is not possible. @@ -450,12 +450,12 @@ Math::BigInt/Math::BigFloat. Load a different math lib, see L<MATH LIBRARY>. - perl -Mbigrat=l,GMP -e 'print 2 ** 512' + perl -Mbigrat=l,GMP -e 'print 2 ** 512' Currently there is no way to specify more than one library on the command line. This means the following does not work: - perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512' + perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512' This will be hopefully fixed soon ;) @@ -477,7 +477,7 @@ overridden in the current scope whenever the bigrat pragma is active. This prints out the name and version of all modules used and then exits. - perl -Mbigrat=v + perl -Mbigrat=v =back @@ -520,33 +520,33 @@ will not happen unless you specifically ask for it with the two import tags "hex" and "oct" - and then it will be global and cannot be disabled inside a scope with "no bigint": - use bigint qw/hex oct/; + use bigint qw/hex oct/; + print hex("0x1234567890123456"); + { + no bigint; print hex("0x1234567890123456"); - { - no bigint; - print hex("0x1234567890123456"); - } + } The second call to hex() will warn about a non-portable constant. Compare this to: - use bigint; + use bigint; - # will warn only under Perl older than v5.9.4 - print hex("0x1234567890123456"); + # will warn only under Perl older than v5.9.4 + print hex("0x1234567890123456"); =back =head1 EXAMPLES - perl -Mbigrat -le 'print sqrt(33)' - perl -Mbigrat -le 'print 2*255' - perl -Mbigrat -le 'print 4.5+2*255' - perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3' - perl -Mbigrat -le 'print 12->is_odd()'; - perl -Mbignum=l,GMP -le 'print 7 ** 7777' + perl -Mbigrat -le 'print sqrt(33)' + perl -Mbigrat -le 'print 2*255' + perl -Mbigrat -le 'print 4.5+2*255' + perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3' + perl -Mbigrat -le 'print 12->is_odd()'; + perl -Mbignum=l,GMP -le 'print 7 ** 7777' =head1 BUGS @@ -588,7 +588,7 @@ L<Math::BigInt::FastCalc>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>. =item * -Peter John Acklam E<lt>pjacklam@gmail.com<gt>, 2014-. +Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2014-. =back diff --git a/cpan/bignum/t/bigint.t b/cpan/bignum/t/bigint.t index 4af592f5c1..5a5c00b72c 100644 --- a/cpan/bignum/t/bigint.t +++ b/cpan/bignum/t/bigint.t @@ -5,7 +5,7 @@ use strict; use warnings; -use Test::More tests => 51; +use Test::More tests => 66; use bigint qw/hex oct/; @@ -87,22 +87,53 @@ is(bigint->round_mode(), 'odd', 'get round mode again'); my $class = 'Math::BigInt'; -is(ref(hex(1)), $class, qq|ref(hex(1)) = $class|); -is(ref(hex(0x1)), $class, qq|ref(hex(0x1)) = $class|); -is(ref(hex("af")), $class, qq|ref(hex("af")) = $class|); -is(ref(hex("0x1")), $class, qq|ref(hex("0x1")) = $class|); - -is(hex("af"), Math::BigInt->new(0xaf), - qq|hex("af") = Math::BigInt->new(0xaf)|); - -is(ref(oct("0x1")), $class, qq|ref(oct("0x1")) = $class|); -is(ref(oct("01")), $class, qq|ref(oct("01")) = $class|); -is(ref(oct("0b01")), $class, qq|ref(oct("0b01")) = $class|); -is(ref(oct("1")), $class, qq|ref(oct("1")) = $class|); -is(ref(oct(" 1")), $class, qq|ref(oct(" 1")) = $class|); -is(ref(oct(" 0x1")), $class, qq|ref(oct(" 0x1")) = $class|); - -is(ref(oct(0x1)), $class, qq|ref(oct(0x1)) = $class|); -is(ref(oct(01)), $class, qq|ref(oct(01)) = $class|); -is(ref(oct(0b01)), $class, qq|ref(oct(0b01)) = $class|); -is(ref(oct(1)), $class, qq|ref(oct(1)) = $class|); +my @table = + ( + + [ 'hex(1)', 1 ], + [ 'hex(01)', 1 ], + [ 'hex(0x1)', 1 ], + [ 'hex("01")', 1 ], + [ 'hex("0x1")', 1 ], + [ 'hex("0X1")', 1 ], + [ 'hex("x1")', 1 ], + [ 'hex("X1")', 1 ], + [ 'hex("af")', 175 ], + + [ 'oct(1)', 1 ], + [ 'oct(01)', 1 ], + [ 'oct(" 1")', 1 ], + + [ 'oct(0x1)', 1 ], + [ 'oct("0x1")', 1 ], + [ 'oct("0X1")', 1 ], + [ 'oct("x1")', 1 ], + [ 'oct("X1")', 1 ], + [ 'oct(" 0x1")', 1 ], + + [ 'oct(0b1)', 1 ], + [ 'oct("0b1")', 1 ], + [ 'oct("0B1")', 1 ], + [ 'oct("b1")', 1 ], + [ 'oct("B1")', 1 ], + [ 'oct(" 0b1")', 1 ], + + #[ 'oct(0o1)', 1 ], # requires Perl 5.33.8 + [ 'oct("01")', 1 ], + [ 'oct("0o1")', 1 ], + [ 'oct("0O1")', 1 ], + [ 'oct("o1")', 1 ], + [ 'oct("O1")', 1 ], + [ 'oct(" 0o1")', 1 ], + + ); + +for my $entry (@table) { + my ($test, $want) = @$entry; + subtest $test, sub { + plan tests => 2; + my $got = eval $test; + cmp_ok($got, '==', $want, 'the output value is correct'); + is(ref($x), $class, 'the reference type is correct'); + }; +} diff --git a/cpan/bignum/t/bignum.t b/cpan/bignum/t/bignum.t index 6bdd5bb29b..f66f8f89aa 100644 --- a/cpan/bignum/t/bignum.t +++ b/cpan/bignum/t/bignum.t @@ -1,9 +1,11 @@ -#!/usr/bin/perl -w +#!perl ############################################################################### use strict; -use Test::More tests => 35; +use warnings; + +use Test::More tests => 50; use bignum qw/oct hex/; @@ -62,22 +64,53 @@ is(bignum->round_mode(), 'odd', 'get round mode again'); my $class = 'Math::BigInt'; -is(ref(hex(1)), $class, qq|ref(hex(1)) = $class|); -is(ref(hex(0x1)), $class, qq|ref(hex(0x1)) = $class|); -is(ref(hex("af")), $class, qq|ref(hex("af")) = $class|); -is(ref(hex("0x1")), $class, qq|ref(hex("0x1")) = $class|); - -is(hex("af"), Math::BigInt->new(0xaf), - qq|hex("af") = Math::BigInt->new(0xaf)|); - -is(ref(oct("0x1")), $class, qq|ref(oct("0x1")) = $class|); -is(ref(oct("01")), $class, qq|ref(oct("01")) = $class|); -is(ref(oct("0b01")), $class, qq|ref(oct("0b01")) = $class|); -is(ref(oct("1")), $class, qq|ref(oct("1")) = $class|); -is(ref(oct(" 1")), $class, qq|ref(oct(" 1")) = $class|); -is(ref(oct(" 0x1")), $class, qq|ref(oct(" 0x1")) = $class|); - -is(ref(oct(0x1)), $class, qq|ref(oct(0x1)) = $class|); -is(ref(oct(01)), $class, qq|ref(oct(01)) = $class|); -is(ref(oct(0b01)), $class, qq|ref(oct(0b01)) = $class|); -is(ref(oct(1)), $class, qq|ref(oct(1)) = $class|); +my @table = + ( + + [ 'hex(1)', 1 ], + [ 'hex(01)', 1 ], + [ 'hex(0x1)', 1 ], + [ 'hex("01")', 1 ], + [ 'hex("0x1")', 1 ], + [ 'hex("0X1")', 1 ], + [ 'hex("x1")', 1 ], + [ 'hex("X1")', 1 ], + [ 'hex("af")', 175 ], + + [ 'oct(1)', 1 ], + [ 'oct(01)', 1 ], + [ 'oct(" 1")', 1 ], + + [ 'oct(0x1)', 1 ], + [ 'oct("0x1")', 1 ], + [ 'oct("0X1")', 1 ], + [ 'oct("x1")', 1 ], + [ 'oct("X1")', 1 ], + [ 'oct(" 0x1")', 1 ], + + [ 'oct(0b1)', 1 ], + [ 'oct("0b1")', 1 ], + [ 'oct("0B1")', 1 ], + [ 'oct("b1")', 1 ], + [ 'oct("B1")', 1 ], + [ 'oct(" 0b1")', 1 ], + + #[ 'oct(0o1)', 1 ], # requires Perl 5.33.8 + [ 'oct("01")', 1 ], + [ 'oct("0o1")', 1 ], + [ 'oct("0O1")', 1 ], + [ 'oct("o1")', 1 ], + [ 'oct("O1")', 1 ], + [ 'oct(" 0o1")', 1 ], + + ); + +for my $entry (@table) { + my ($test, $want) = @$entry; + subtest $test, sub { + plan tests => 2; + my $got = eval $test; + cmp_ok($got, '==', $want, 'the output value is correct'); + is(ref($x), $class, 'the reference type is correct'); + }; +} diff --git a/cpan/bignum/t/bigrat.t b/cpan/bignum/t/bigrat.t index ac6fc0c6db..23f8f81cdf 100644 --- a/cpan/bignum/t/bigrat.t +++ b/cpan/bignum/t/bigrat.t @@ -5,7 +5,7 @@ use strict; use warnings; -use Test::More tests => 40; +use Test::More tests => 55; use bigrat qw/oct hex/; @@ -63,22 +63,53 @@ is(bigrat->round_mode(), 'odd', 'get round mode again'); my $class = 'Math::BigInt'; -is(ref(hex(1)), $class, qq|ref(hex(1)) = $class|); -is(ref(hex(0x1)), $class, qq|ref(hex(0x1)) = $class|); -is(ref(hex("af")), $class, qq|ref(hex("af")) = $class|); -is(ref(hex("0x1")), $class, qq|ref(hex("0x1")) = $class|); - -is(hex("af"), Math::BigInt->new(0xaf), - qq|hex("af") = Math::BigInt->new(0xaf)|); - -is(ref(oct("0x1")), $class, qq|ref(oct("0x1")) = $class|); -is(ref(oct("01")), $class, qq|ref(oct("01")) = $class|); -is(ref(oct("0b01")), $class, qq|ref(oct("0b01")) = $class|); -is(ref(oct("1")), $class, qq|ref(oct("1")) = $class|); -is(ref(oct(" 1")), $class, qq|ref(oct(" 1")) = $class|); -is(ref(oct(" 0x1")), $class, qq|ref(oct(" 0x1")) = $class|); - -is(ref(oct(0x1)), $class, qq|ref(oct(0x1)) = $class|); -is(ref(oct(01)), $class, qq|ref(oct(01)) = $class|); -is(ref(oct(0b01)), $class, qq|ref(oct(0b01)) = $class|); -is(ref(oct(1)), $class, qq|ref(oct(1)) = $class|); +my @table = + ( + + [ 'hex(1)', 1 ], + [ 'hex(01)', 1 ], + [ 'hex(0x1)', 1 ], + [ 'hex("01")', 1 ], + [ 'hex("0x1")', 1 ], + [ 'hex("0X1")', 1 ], + [ 'hex("x1")', 1 ], + [ 'hex("X1")', 1 ], + [ 'hex("af")', 175 ], + + [ 'oct(1)', 1 ], + [ 'oct(01)', 1 ], + [ 'oct(" 1")', 1 ], + + [ 'oct(0x1)', 1 ], + [ 'oct("0x1")', 1 ], + [ 'oct("0X1")', 1 ], + [ 'oct("x1")', 1 ], + [ 'oct("X1")', 1 ], + [ 'oct(" 0x1")', 1 ], + + [ 'oct(0b1)', 1 ], + [ 'oct("0b1")', 1 ], + [ 'oct("0B1")', 1 ], + [ 'oct("b1")', 1 ], + [ 'oct("B1")', 1 ], + [ 'oct(" 0b1")', 1 ], + + #[ 'oct(0o1)', 1 ], # requires Perl 5.33.8 + [ 'oct("01")', 1 ], + [ 'oct("0o1")', 1 ], + [ 'oct("0O1")', 1 ], + [ 'oct("o1")', 1 ], + [ 'oct("O1")', 1 ], + [ 'oct(" 0o1")', 1 ], + + ); + +for my $entry (@table) { + my ($test, $want) = @$entry; + subtest $test, sub { + plan tests => 2; + my $got = eval $test; + cmp_ok($got, '==', $want, 'the output value is correct'); + is(ref($x), $class, 'the reference type is correct'); + }; +} diff --git a/cpan/bignum/t/option_l.t b/cpan/bignum/t/option_l.t index c3a1d5d328..25ca325f3e 100644 --- a/cpan/bignum/t/option_l.t +++ b/cpan/bignum/t/option_l.t @@ -22,13 +22,13 @@ $rc = eval { bignum->import( "l" => "foo" ) }; is($@, '', # shouldn't die qq|eval { bignum->import( "l" => "foo" ) }|); is(scalar(@WARNINGS), 1, 'one warning'); -like($WARNINGS[0], qr/fallback to Math::/, 'got fallback'); +like($WARNINGS[0], qr/using fallback/, 'using fallback'); $rc = eval { bignum->import( "lib" => "foo" ) }; is($@, '', # ditto qq|eval { bignum->import( "lib" => "foo" ) }|); is(scalar @WARNINGS, 2, 'two warnings'); -like($WARNINGS[1], qr/fallback to Math::/, 'got fallback'); +like($WARNINGS[1], qr/using fallback/, 'using fallback'); $rc = eval { bignum->import( "try" => "foo" ) }; is($@, '', # shouldn't die @@ -42,7 +42,7 @@ $rc = eval { bignum->import( "foo" => "bar" ) }; like($@, qr/^Unknown option foo/i, 'died'); # should die $rc = eval { bignum->import( "only" => "bar" ) }; -like($@, qr/fallback disallowed/i, 'died'); # should die +like($@, qr/fallback.*disallowed/i, 'died'); # should die # test that options are only lowercase (don't see a reason why allow UPPER) |