diff options
author | Neil Bowers <neilb@neilb.org> | 2021-12-20 17:03:10 +0000 |
---|---|---|
committer | Neil Bowers <neilb@neilb.org> | 2021-12-20 18:01:25 +0000 |
commit | 02895be6409217e776eaab0bb605f268ccdf20bb (patch) | |
tree | dafc8121b889d0b0f5175009f9d5188a4b6fc60e | |
parent | 96eb178841c84cf94d6dbe5f5ce355282a005d45 (diff) | |
download | perl-02895be6409217e776eaab0bb605f268ccdf20bb.tar.gz |
Updated dual-life modules for 5.35.7
26 files changed, 2060 insertions, 160 deletions
@@ -309,6 +309,7 @@ cpan/CPAN/PAUSE2005.pub CPAN public key cpan/CPAN/PAUSE2007.pub CPAN public key cpan/CPAN/PAUSE2009.pub CPAN public key cpan/CPAN/PAUSE2011.pub +cpan/CPAN/PAUSE2022.pub cpan/CPAN/scripts/cpan easily interact with CPAN from the command line cpan/CPAN/t/01loadme.t See if CPAN the module works cpan/CPAN/t/02nox.t See if CPAN::Nox works @@ -1358,6 +1359,8 @@ cpan/Math-BigInt/t/bnstr-mbf.t Test Math::BigInt cpan/Math-BigInt/t/bnstr-mbi.t Test Math::BigInt cpan/Math-BigInt/t/bpi-mbf.t cpan/Math-BigInt/t/bpi-mbi.t +cpan/Math-BigInt/t/bpow-mbf.t +cpan/Math-BigInt/t/bpow-mbi.t cpan/Math-BigInt/t/bsstr-mbf.t Test Math::BigInt cpan/Math-BigInt/t/bsstr-mbi.t Test Math::BigInt cpan/Math-BigInt/t/buparrow-mbi.t Test Math::BigInt @@ -1374,6 +1377,8 @@ cpan/Math-BigInt/t/dparts-mbf.t Test Math::BigInt 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/fparts-mbf.t +cpan/Math-BigInt/t/fparts-mbi.t 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 @@ -166,5 +166,5 @@ } }, "version" : "5.035007", - "x_serialization_backend" : "JSON::PP version 4.06" + "x_serialization_backend" : "JSON::PP version 4.07" } diff --git a/Porting/Maintainers.pl b/Porting/Maintainers.pl index fd9b63793a..6e0544f6bc 100755 --- a/Porting/Maintainers.pl +++ b/Porting/Maintainers.pl @@ -186,7 +186,7 @@ use File::Glob qw(:case); }, 'bignum' => { - 'DISTRIBUTION' => 'PJACKLAM/bignum-0.53.tar.gz', + 'DISTRIBUTION' => 'PJACKLAM/bignum-0.63.tar.gz', 'FILES' => q[cpan/bignum], 'EXCLUDED' => [ qr{^xt/}, @@ -250,7 +250,7 @@ use File::Glob qw(:case); }, 'CPAN' => { - 'DISTRIBUTION' => 'ANDK/CPAN-2.28.tar.gz', + 'DISTRIBUTION' => 'ANDK/CPAN-2.29.tar.gz', 'FILES' => q[cpan/CPAN], 'EXCLUDED' => [ qr{^distroprefs/}, @@ -676,7 +676,7 @@ use File::Glob qw(:case); }, 'JSON::PP' => { - 'DISTRIBUTION' => 'ISHIGAKI/JSON-PP-4.06.tar.gz', + 'DISTRIBUTION' => 'ISHIGAKI/JSON-PP-4.07.tar.gz', 'FILES' => q[cpan/JSON-PP], }, @@ -728,7 +728,7 @@ use File::Glob qw(:case); }, 'Math::BigInt' => { - 'DISTRIBUTION' => 'PJACKLAM/Math-BigInt-1.999827.tar.gz', + 'DISTRIBUTION' => 'PJACKLAM/Math-BigInt-1.999828.tar.gz', 'FILES' => q[cpan/Math-BigInt], 'EXCLUDED' => [ qr{^xt/}, diff --git a/cpan/CPAN/PAUSE2022.pub b/cpan/CPAN/PAUSE2022.pub new file mode 100644 index 0000000000..728e4bad65 --- /dev/null +++ b/cpan/CPAN/PAUSE2022.pub @@ -0,0 +1,598 @@ +gpg --export --armor 450F89EC +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQGiBD4+cJARBACxOByY0SJBBuJoFrH2hoqRFny423gY6V3jq1uTgGY/PPaxP+Sq +r3RzxPct4vJcsoo48pwBsMHLrWfORq26zb6eKgmMq/CQo2gzaRbeRxCi3ke4KBmu +aREi6RjaZSU94yABtDmspUBrpYV8zfZMv5ZIQlg9W1Tu66BFOUrrNeDpKwCgosCp +9dtNAMhHkzxs8UJH5i3Uzb0D/0VLoAE8sOfUXqjc38rxiHuGBFSNC70Ih4mzGUCJ +MGT4z1X3K6uUawnXMoc8XqPaYnEgOzztMymydtr+urjUwcGnuXDSpV6nulE5irxh +zlikSTJy/42QzTMcrdRynffmJo9PRgymMI8GgWaYG5g3zzGAhi5BA6G8JKfC93IV +xiRPBACXJpLBYQljqJY9UDNJuq8nHhKiWHBXdZzrC3LM0FSF3PKuP/ugc+KBIKXm +clNPNFKla/SRbH6dMHsGIy8wnGPI5AtTS0roNQrttv3/ghRT7+OKXrGmBxZ/KHVr +v3PVgiRA5MDr1mIsovfuc9WQnFu2TkgnN/F3pDcrVVSi5b+rZLQzUEFVU0UgQmF0 +Y2ggU2lnbmluZyBLZXkgMjAwOSA8cGF1c2VAcGF1c2UucGVybC5vcmc+iGYEExEC +ACYFAkl43/ECGwMFCQ/OdIAGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRAyjahn +RQ+J7IDEAJ40F0fyg6NTAZ2nWizs/C/RSPYPsgCfSqnVpaqF6k0H/5AabfdNbcS2 +Wm6IRgQQEQIABgUCSXwU9wAKCRDsgDnwoxfBXQBsAJsEku5xBZsf7EYYkWeSEiXn +p2kLtQCg0V2hlzJnDCFFqf/WsMqL2glkDjOIRgQQEQIABgUCS4xI1gAKCRA0rq6z +PNGwzHiqAJ0dtAvhlqh/mH7rk1zV5d6MKUKBZQCg5lO06lB5gPX+RrxJrJ/2ThyQ +auGIRgQREQIABgUCScuA1AAKCRA2zBWk41ll/N3WAJ9aV3ZzqMCiXbFrQwKLAtyr +h6wI3wCfYKAvs67QENDfq4bvTHk0N61MA1eIRgQTEQIABgUCSpht5gAKCRDp1n4q +3kFyFnQ7AKCaTGJjbuTiGwPjxRSYLdWahh9q3gCfTYZNWq1+9I4I01veU166Nh7G +1KGIZgQTEQIAJgIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheABQJNc/PEBQkTkilo +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 +55YO2ILV37fmSQ57ezqz1yw= +=NaWa +-----END PGP PUBLIC KEY BLOCK----- diff --git a/cpan/CPAN/lib/CPAN.pm b/cpan/CPAN/lib/CPAN.pm index c93d98e8db..d1deccc4e2 100644 --- a/cpan/CPAN/lib/CPAN.pm +++ b/cpan/CPAN/lib/CPAN.pm @@ -2,7 +2,7 @@ # vim: ts=4 sts=4 sw=4: use strict; package CPAN; -$CPAN::VERSION = '2.28'; +$CPAN::VERSION = '2.29'; $CPAN::VERSION =~ s/_//; # we need to run chdir all over and we would get at wrong libraries @@ -549,8 +549,9 @@ sub _yaml_module () { # CPAN::_yaml_loadfile sub _yaml_loadfile { - my($self,$local_file) = @_; + my($self,$local_file,$opt) = @_; return +[] unless -s $local_file; + my $opt_loadblessed = $opt->{loadblessed} || $CPAN::Config->{yaml_load_code} || 0; my $yaml_module = _yaml_module; if ($CPAN::META->has_inst($yaml_module)) { # temporarily enable yaml code deserialisation @@ -560,7 +561,7 @@ sub _yaml_loadfile { my $old_loadcode = ${"$yaml_module\::LoadCode"}; my $old_loadblessed = ${"$yaml_module\::LoadBlessed"}; ${ "$yaml_module\::LoadCode" } = $CPAN::Config->{yaml_load_code} || 0; - ${ "$yaml_module\::LoadBlessed" } = 1; + ${ "$yaml_module\::LoadBlessed" } = $opt_loadblessed ? 1 : 0; my ($code, @yaml); if ($code = UNIVERSAL::can($yaml_module, "LoadFile")) { @@ -1114,6 +1115,28 @@ sub has_usable { sub {require Net::FTP}, sub {require Net::Config}, ], + 'IO::Socket::SSL' => [ + sub { + require IO::Socket::SSL; + unless (CPAN::Version->vge(IO::Socket::SSL::->VERSION,1.56)) { + for ("Will not use IO::Socket::SSL, need 1.56\n") { + $CPAN::Frontend->mywarn($_); + die $_; + } + } + } + ], + 'Net::SSLeay' => [ + sub { + require Net::SSLeay; + unless (CPAN::Version->vge(Net::SSLeay::->VERSION,1.49)) { + for ("Will not use Net::SSLeay, need 1.49\n") { + $CPAN::Frontend->mywarn($_); + die $_; + } + } + } + ], 'HTTP::Tiny' => [ sub { require HTTP::Tiny; @@ -2252,6 +2275,8 @@ currently defined: prefs_dir local directory to store per-distro build options proxy_user username for accessing an authenticating proxy proxy_pass password for accessing an authenticating proxy + pushy_https use https to cpan.org when possible, otherwise use http + to cpan.org and issue a warning randomize_urllist add some randomness to the sequence of the urllist recommends_policy whether recommended prerequisites should be included scan_cache controls scanning of cache ('atstart', 'atexit' or 'never') diff --git a/cpan/CPAN/lib/CPAN/Distribution.pm b/cpan/CPAN/lib/CPAN/Distribution.pm index 3412108539..cf39833d8a 100644 --- a/cpan/CPAN/lib/CPAN/Distribution.pm +++ b/cpan/CPAN/lib/CPAN/Distribution.pm @@ -9,7 +9,7 @@ use File::Path (); use POSIX ":sys_wait_h"; @CPAN::Distribution::ISA = qw(CPAN::InfoObj); use vars qw($VERSION); -$VERSION = "2.27"; +$VERSION = "2.29"; my $run_allow_installing_within_test = 1; # boolean; either in test or in install, there is no third option @@ -1473,18 +1473,32 @@ sub SIG_check_file { my($self,$chk_file) = @_; my $rv = eval { Module::Signature::_verify($chk_file) }; - if ($rv == Module::Signature::SIGNATURE_OK()) { + if ($rv eq Module::Signature::CANNOT_VERIFY()) { + $CPAN::Frontend->myprint(qq{\nSignature for }. + qq{file $chk_file could not be verified for an unknown reason. }. + $self->as_string. + qq{Module::Signature verification returned value $rv\n\n} + ); + + my $wrap = qq{The manual says for this case: Cannot verify the +OpenPGP signature, maybe due to the lack of a network connection to +the key server, or if neither gnupg nor Crypt::OpenPGP exists on the +system. You probably want to analyse the situation and if you cannot +fix it you will have to decide whether you want to stop this session +or you want to turn off signature verification. The latter would be +done with the command 'o conf init check_sigs'}; + + $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap)); + } if ($rv == Module::Signature::SIGNATURE_OK()) { $CPAN::Frontend->myprint("Signature for $chk_file ok\n"); return $self->{SIG_STATUS} = "OK"; } else { - $CPAN::Frontend->myprint(qq{\nSignature invalid for }. - qq{distribution file. }. + $CPAN::Frontend->mywarn(qq{\nSignature invalid for }. + qq{file $chk_file. }. qq{Please investigate.\n\n}. - $self->as_string, - $CPAN::META->instance( - 'CPAN::Author', - $self->cpan_userid - )->as_string); + $self->as_string. + qq{Module::Signature verification returned value $rv\n\n} + ); my $wrap = qq{I\'d recommend removing $chk_file. Its signature is invalid. Maybe you have configured your 'urllist' with @@ -1519,20 +1533,43 @@ sub CHECKSUM_check_file { $file = $self->{localfile}; $basename = File::Basename::basename($file); + my($signed_data); my $fh = FileHandle->new; - if (open $fh, $chk_file) { - local($/); - my $eval = <$fh>; - $eval =~ s/\015?\012/\n/g; - close $fh; - my($compmt) = Safe->new(); - $cksum = $compmt->reval($eval); - if ($@) { - rename $chk_file, "$chk_file.bad"; - Carp::confess($@) if $@; + if ($check_sigs) { + my $tempdir; + if ($CPAN::META->has_usable("File::Temp")) { + $tempdir = File::Temp::tempdir("CHECKSUMS-XXXX", CLEANUP => 1, DIR => "/tmp" ); + } else { + $tempdir = File::Spec->catdir(File::Spec->tmpdir, "CHECKSUMS-$$"); + File::Path::mkpath($tempdir); } + my $tempfile = File::Spec->catfile($tempdir, "CHECKSUMS.$$"); + unlink $tempfile; # ignore missing file + my $gpg = $CPAN::Config->{gpg} or + $CPAN::Frontend->mydie("Your configuration suggests that you do not have 'gpg' installed. This is needed to verify checksums with the config variable 'check_sigs' on. Please configure it with 'o conf init gpg'"); + my $system = "gpg --verify --batch --no-tty --output $tempfile $chk_file 2> /dev/null"; + 0 == system $system or $CPAN::Frontend->mydie("gpg run was failing, cannot continue: $system"); + open $fh, $tempfile or $CPAN::Frontend->mydie("Could not open $tempfile: $!"); + local $/; + $signed_data = <$fh>; + close $fh; + File::Path::rmtree($tempdir); } else { - Carp::carp "Could not open $chk_file for reading"; + my $fh = FileHandle->new; + if (open $fh, $chk_file) { + local($/); + $signed_data = <$fh>; + } else { + $CPAN::Frontend->mydie("Could not open $chk_file for reading"); + } + close $fh; + } + $signed_data =~ s/\015?\012/\n/g; + my($compmt) = Safe->new(); + $cksum = $compmt->reval($signed_data); + if ($@) { + rename $chk_file, "$chk_file.bad"; + Carp::confess($@) if $@; } if (! ref $cksum or ref $cksum ne "HASH") { @@ -1546,6 +1583,30 @@ for further processing, but got garbage instead. $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n"); $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS file broken"; return; + } elsif (exists $cksum->{$basename} && ! exists $cksum->{$basename}{cpan_path}) { + $CPAN::Frontend->mywarn(qq{ +Warning: checksum file '$chk_file' not conforming. + +The cksum does not contain the key 'cpan_path' for '$basename'. +}); + my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed nonetheless?", "no"); + $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n"); + $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS file without cpan_path"; + return; + } elsif (exists $cksum->{$basename} && substr($self->{ID},0,length($cksum->{$basename}{cpan_path})) + ne $cksum->{$basename}{cpan_path}) { + $CPAN::Frontend->mywarn(qq{ +Warning: checksum file not matching path '$self->{ID}'. + +The cksum contain the key 'cpan_path=$cksum->{$basename}{cpan_path}' +which does not match the ID of the distribution '$self->{ID}'. +Something's suspicious might be going on here. Please investigate. + +}); + my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed nonetheless?", "no"); + $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n"); + $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS non-matching cpan_path vs. ID"; + return; } elsif (exists $cksum->{$basename}{sha256}) { $self->debug("Found checksum for $basename:" . "$cksum->{$basename}{sha256}\n") if $CPAN::DEBUG; diff --git a/cpan/CPAN/lib/CPAN/FTP.pm b/cpan/CPAN/lib/CPAN/FTP.pm index 268522f78f..8193309c27 100644 --- a/cpan/CPAN/lib/CPAN/FTP.pm +++ b/cpan/CPAN/lib/CPAN/FTP.pm @@ -15,7 +15,7 @@ use vars qw($connect_to_internet_ok $Ua $Thesite $ThesiteURL $Themethod); use vars qw( $VERSION ); -$VERSION = "5.5013"; +$VERSION = "5.5014"; sub _plus_append_open { my($fh, $file) = @_; @@ -63,7 +63,7 @@ sub _ftp_statistics { _plus_append_open($fh, $file); } } - my $stats = eval { CPAN->_yaml_loadfile($file); }; + my $stats = eval { CPAN->_yaml_loadfile($file, {loadblessed => 1}); }; if ($@) { if (ref $@) { if (ref $@ eq "CPAN::Exception::yaml_not_installed") { @@ -319,6 +319,175 @@ sub localize { my $longmess = Carp::longmess(); $self->debug("file[$file] aslocal[$aslocal] force[$force] carplongmess[$longmess]"); } + for ($CPAN::Config->{connect_to_internet_ok}) { + $connect_to_internet_ok = $_ if not defined $connect_to_internet_ok and defined $_; + } + my $ph = $CPAN::Config->{pushy_https}; + if (!defined $ph || $ph) { + return $self->localize_2021($file,$aslocal,$force,$with_defaults); + } else { + return $self->localize_1995ff($file,$aslocal,$force,$with_defaults); + } +} + +sub have_promising_aslocal { + my($self, $aslocal, $force) = @_; + if (-f $aslocal && -r _ && !($force & 1)) { + my $size; + if ($size = -s $aslocal) { + $self->debug("aslocal[$aslocal]size[$size]") if $CPAN::DEBUG; + return 1; + } else { + # empty file from a previous unsuccessful attempt to download it + unlink $aslocal or + $CPAN::Frontend->mydie("Found a zero-length '$aslocal' that I ". + "could not remove."); + } + } + return; +} + +#-> sub CPAN::FTP::localize ; +sub localize_2021 { + my($self,$file,$aslocal,$force,$with_defaults) = @_; + return $aslocal if $self->have_promising_aslocal($aslocal, $force); + my($aslocal_dir) = dirname($aslocal); + my $ret; + $self->mymkpath($aslocal_dir); + my $aslocal_tempfile = $aslocal . ".tmp" . $$; + my $base; + if ( + ($CPAN::META->has_usable('HTTP::Tiny') + && $CPAN::META->has_usable('Net::SSLeay') + && $CPAN::META->has_usable('IO::Socket::SSL') + ) + || $CPAN::Config->{curl} + || $CPAN::Config->{wget} + ) { + for my $prx (qw(https_proxy no_proxy)) { + $ENV{$prx} = $CPAN::Config->{$prx} if $CPAN::Config->{$prx}; + } + $base = "https://cpan.org/"; + } else { + my @missing_modules = grep { ! $CPAN::META->has_usable($_) } qw(HTTP::Tiny Net::SSLeay IO::Socket::SSL); + my $miss = join ", ", map { "'$_'" } @missing_modules; + my $modules = @missing_modules == 1 ? "module" : "modules"; + $CPAN::Frontend->mywarn("Missing or unusable $modules $miss, and found neither curl nor wget installed. Need to fall back to http.\n"); + for my $prx (qw(http_proxy no_proxy)) { + $ENV{$prx} = $CPAN::Config->{$prx} if $CPAN::Config->{$prx}; + } + $base = "http://www.cpan.org/"; + } + $ret = $self->hostdl_2021($base,$file,$aslocal_tempfile); + if ($ret) { # c&p from below + CPAN->debug("ret[$ret]aslocal[$aslocal]") if $CPAN::DEBUG; + if ($ret eq $aslocal_tempfile) { + # if we got it exactly as we asked for, only then we + # want to rename + rename $aslocal_tempfile, $aslocal + or $CPAN::Frontend->mydie("Error while trying to rename ". + "'$ret' to '$aslocal': $!"); + $ret = $aslocal; + } + } else { + unlink $aslocal_tempfile; + return; + } + return $ret; +} + +sub hostdl_2021 { + my($self, $base, $file, $aslocal) = @_; # the $aslocal is $aslocal_tempfile in the caller (old convention) + my $proxy_vars = $self->_proxy_vars($base); + my $url = "$base$file"; + if ($CPAN::META->has_usable('HTTP::Tiny')) { + # mostly c&p from below + require CPAN::HTTP::Client; + my $chc = CPAN::HTTP::Client->new( + proxy => $CPAN::Config->{http_proxy} || $ENV{http_proxy}, + no_proxy => $CPAN::Config->{no_proxy} || $ENV{no_proxy}, + ); + for my $try ( $url, ( $url !~ /\.gz(?!\n)\Z/ ? "$url.gz" : () ) ) { + $CPAN::Frontend->myprint("Fetching with HTTP::Tiny:\n$try\n"); + my $res = eval { $chc->mirror($try, $aslocal) }; + if ( $res && $res->{success} ) { + my $now = time; + utime $now, $now, $aslocal; # download time is more + # important than upload + # time + return $aslocal; + } + elsif ( $res && $res->{status} ne '599') { + $CPAN::Frontend->myprint(sprintf( + "HTTP::Tiny failed with code[%s] message[%s]\n", + $res->{status}, + $res->{reason}, + ) + ); + } + elsif ( $res && $res->{status} eq '599') { + $CPAN::Frontend->myprint(sprintf( + "HTTP::Tiny failed with an internal error: %s\n", + $res->{content}, + ) + ); + } + else { + my $err = $@ || 'Unknown error'; + $CPAN::Frontend->myprint(sprintf( + "Error downloading with HTTP::Tiny: %s\n", $err + ) + ); + } + } + } elsif ($CPAN::Config->{curl} || $CPAN::Config->{wget}){ + # c&p from further down + my($src_switch, $stdout_redir); + my($devnull) = $CPAN::Config->{devnull} || ""; + DLPRG: for my $dlprg (qw(curl wget)) { + my $dlprg_configured = $CPAN::Config->{$dlprg}; + next unless defined $dlprg_configured; + my $funkyftp = CPAN::HandleConfig->safe_quote($dlprg_configured); + if ($dlprg eq "wget") { + $src_switch = " -O \"$aslocal\""; + $stdout_redir = ""; + } elsif ($dlprg eq 'curl') { + $src_switch = ' -L -f -s -S --netrc-optional'; + if ($proxy_vars->{http_proxy}) { + $src_switch .= qq{ -U "$proxy_vars->{proxy_user}:$proxy_vars->{proxy_pass}" -x "$proxy_vars->{http_proxy}"}; + } + } + $CPAN::Frontend->myprint( + qq[ +Trying with + $funkyftp$src_switch +to get + $url +]); + my($system) = + "$funkyftp$src_switch \"$url\" $devnull$stdout_redir"; + $self->debug("system[$system]") if $CPAN::DEBUG; + my($wstatus) = system($system); + if ($wstatus == 0) { + return $aslocal; + } else { + my $estatus = $wstatus >> 8; + my $size = -f $aslocal ? + ", left\n$aslocal with size ".-s _ : + "\nWarning: expected file [$aslocal] doesn't exist"; + $CPAN::Frontend->myprint(qq{ + Function system("$system") + returned status $estatus (wstat $wstatus)$size + }); + } + } # DLPRG + } # curl, wget + return; +} + +#-> sub CPAN::FTP::localize ; +sub localize_1995ff { + my($self,$file,$aslocal,$force,$with_defaults) = @_; if ($^O eq 'MacOS') { # Comment by AK on 2000-09-03: Uniq short filenames would be # available in CHECKSUMS file @@ -343,18 +512,7 @@ sub localize { } } - if (-f $aslocal && -r _ && !($force & 1)) { - my $size; - if ($size = -s $aslocal) { - $self->debug("aslocal[$aslocal]size[$size]") if $CPAN::DEBUG; - return $aslocal; - } else { - # empty file from a previous unsuccessful attempt to download it - unlink $aslocal or - $CPAN::Frontend->mydie("Found a zero-length '$aslocal' that I ". - "could not remove."); - } - } + return $aslocal if $self->have_promising_aslocal($aslocal, $force); my($maybe_restore) = 0; if (-f $aslocal) { rename $aslocal, "$aslocal.bak$$"; @@ -433,9 +591,6 @@ sub localize { $CPAN::Config->{ftp_passive} : 1; my $ret; my $stats = $self->_new_stats($file); - for ($CPAN::Config->{connect_to_internet_ok}) { - $connect_to_internet_ok = $_ if not defined $connect_to_internet_ok and defined $_; - } LEVEL: for $levelno (0..$#levels) { my $level_tuple = $levels[$levelno]; my($level,$scheme,$sitetag) = @$level_tuple; diff --git a/cpan/CPAN/lib/CPAN/FirstTime.pm b/cpan/CPAN/lib/CPAN/FirstTime.pm index 310e73abef..9534c4d55b 100644 --- a/cpan/CPAN/lib/CPAN/FirstTime.pm +++ b/cpan/CPAN/lib/CPAN/FirstTime.pm @@ -11,7 +11,7 @@ use File::Spec (); use CPAN::Mirrors (); use CPAN::Version (); use vars qw($VERSION $auto_config); -$VERSION = "5.5315"; +$VERSION = "5.5316"; =head1 NAME @@ -451,6 +451,20 @@ Please set your policy to one of the three values. Policy on building prerequisites (follow, ask or ignore)? +=item pushy_https + +Boolean. Defaults to true. If this option is true, the cpan shell will +use https://cpan.org/ to download stuff from the CPAN. It will fall +back to http://cpan.org/ if it can't handle https for some reason +(missing modules, missing programs). Whenever it falls back to the +http protocol, it will issue a warning. + +If this option is true, the option C<urllist> will be ignored. +Consequently, if you want to work with local mirrors via your own +configured list of URLs, you will have to choose no below. + +Do you want to turn the pushy_https behaviour on? + =item randomize_urllist CPAN.pm can introduce some randomness when using hosts for download @@ -1315,6 +1329,7 @@ sub init { # Let's assume they want to use the internet and make them turn it # off if they really don't. my_yn_prompt("connect_to_internet_ok" => 1, $matcher); + my_yn_prompt("pushy_https" => 1, $matcher); # Allow matching but don't show during manual config if ($matcher) { @@ -1344,7 +1359,11 @@ sub init { ); } else { - $CPAN::Config->{urllist} = [ 'http://www.cpan.org/' ]; + # Hint: as of 2021-11: to get http, use http://www.cpan.org/ + $CPAN::Config->{urllist} = [ 'https://cpan.org/' ]; + $CPAN::Frontend->myprint( + "We initialized your 'urllist' to @{$CPAN::Config->{urllist}}. Type 'o conf init urllist' to change it.\n" + ); } } elsif (!$matcher || "urllist" =~ $matcher) { diff --git a/cpan/CPAN/lib/CPAN/HandleConfig.pm b/cpan/CPAN/lib/CPAN/HandleConfig.pm index e24a969c11..c9d0dc7056 100644 --- a/cpan/CPAN/lib/CPAN/HandleConfig.pm +++ b/cpan/CPAN/lib/CPAN/HandleConfig.pm @@ -12,7 +12,7 @@ CPAN::HandleConfig - internal configuration handling for CPAN.pm =cut -$VERSION = "5.5011"; # see also CPAN::Config::VERSION at end of file +$VERSION = "5.5012"; # see also CPAN::Config::VERSION at end of file %can = ( commit => "Commit changes to disk", @@ -25,8 +25,9 @@ $VERSION = "5.5011"; # see also CPAN::Config::VERSION at end of file # A1: svn diff -r 757:758 # where dagolden added test_report [git e997b71de88f1019a1472fc13cb97b1b7f96610f] # A2: svn diff -r 985:986 # where andk added yaml_module [git 312b6d9b12b1bdec0b6e282d853482145475021f] # A3: 1. add new config option to %keys below -# 2. add a Pod description in CPAN::FirstTime; it should include a -# prompt line; see others for examples +# 2. add a Pod description in CPAN::FirstTime in the DESCRIPTION +# section; it should include a prompt line; see others for +# examples # 3. add a "matcher" section in CPAN::FirstTime::init that includes # a prompt function; see others for examples # 4. add config option to documentation section in CPAN.pm @@ -98,6 +99,7 @@ $VERSION = "5.5011"; # see also CPAN::Config::VERSION at end of file "prerequisites_policy", "proxy_pass", "proxy_user", + "pushy_https", "randomize_urllist", "recommends_policy", "scan_cache", @@ -561,6 +563,23 @@ sub load { my @miss = $self->missing_config_data; CPAN->debug("do_init[$do_init]loading[$loading]miss[@miss]") if $CPAN::DEBUG; return unless $do_init || @miss; + if (@miss==1 and $miss[0] eq "pushy_https" && !$do_init) { + $CPAN::Frontend->myprint(<<'END'); + +Starting with version 2.29 of the cpan shell, a new download mechanism +is the default which exclusively uses cpan.org as the host to download +from. The configuration variable pushy_https can be used to (de)select +the new mechanism. Please read more about it and make your choice +between the old and the new mechanism by running + + o conf init pushy_https + +Once you have done that and stored the config variable this dialog +will disappear. +END + + return; + } # I'm not how we'd ever wind up in a recursive loop, but I'm leaving # this here for safety's sake -- dagolden, 2011-01-19 @@ -677,6 +696,7 @@ sub missing_config_data { "no_proxy", #"pager", "prerequisites_policy", + "pushy_https", "scan_cache", #"tar", #"unzip", @@ -776,7 +796,7 @@ sub prefs_lookup { use strict; use vars qw($AUTOLOAD $VERSION); - $VERSION = "5.5011"; + $VERSION = "5.5012"; # formerly CPAN::HandleConfig was known as CPAN::Config sub AUTOLOAD { ## no critic diff --git a/cpan/CPAN/lib/CPAN/Index.pm b/cpan/CPAN/lib/CPAN/Index.pm index 59e75dcaee..06b16b6958 100644 --- a/cpan/CPAN/lib/CPAN/Index.pm +++ b/cpan/CPAN/lib/CPAN/Index.pm @@ -1,7 +1,7 @@ package CPAN::Index; use strict; use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03 $HAVE_REANIMATED $VERSION); -$VERSION = "2.12"; +$VERSION = "2.29"; @CPAN::Index::ISA = qw(CPAN::Debug); $LAST_TIME ||= 0; $DATE_OF_03 ||= 0; @@ -137,7 +137,7 @@ sub reanimate_build_dir { )); DISTRO: for $i (0..$#candidates) { my $dirent = $candidates[$i]; - my $y = eval {CPAN->_yaml_loadfile(File::Spec->catfile($d,$dirent))}; + my $y = eval {CPAN->_yaml_loadfile(File::Spec->catfile($d,$dirent), {loadblessed => 1})}; if ($@) { warn "Error while parsing file '$dirent'; error: '$@'"; next DISTRO; diff --git a/cpan/JSON-PP/lib/JSON/PP.pm b/cpan/JSON-PP/lib/JSON/PP.pm index 2475fe1e87..ff23fc7c0f 100644 --- a/cpan/JSON-PP/lib/JSON/PP.pm +++ b/cpan/JSON-PP/lib/JSON/PP.pm @@ -14,7 +14,7 @@ use JSON::PP::Boolean; use Carp (); #use Devel::Peek; -$JSON::PP::VERSION = '4.06'; +$JSON::PP::VERSION = '4.07'; @JSON::PP::EXPORT = qw(encode_json decode_json from_json to_json); @@ -1563,6 +1563,11 @@ sub incr_parse { } } + unless ( $coder->get_utf8 ) { + utf8::upgrade( $self->{incr_text} ); + utf8::decode( $self->{incr_text} ); + } + my ($obj, $offset) = $coder->PP_decode_json( $self->{incr_text}, 0x00000001 ); push @ret, $obj; use bytes; @@ -1770,10 +1775,6 @@ JSON::PP - JSON::XS compatible pure-Perl module. use JSON; -=head1 VERSION - - 4.05 - =head1 DESCRIPTION JSON::PP is a pure perl JSON decoder/encoder, and (almost) compatible to much diff --git a/cpan/JSON-PP/lib/JSON/PP/Boolean.pm b/cpan/JSON-PP/lib/JSON/PP/Boolean.pm index a6b9ee1137..d1ee0a477c 100644 --- a/cpan/JSON-PP/lib/JSON/PP/Boolean.pm +++ b/cpan/JSON-PP/lib/JSON/PP/Boolean.pm @@ -10,7 +10,7 @@ overload::import('overload', fallback => 1, ); -$JSON::PP::Boolean::VERSION = '4.06'; +$JSON::PP::Boolean::VERSION = '4.07'; 1; diff --git a/cpan/JSON-PP/t/105_esc_slash.t b/cpan/JSON-PP/t/105_esc_slash.t index 56f415cf02..ae2d7d207b 100644 --- a/cpan/JSON-PP/t/105_esc_slash.t +++ b/cpan/JSON-PP/t/105_esc_slash.t @@ -1,6 +1,6 @@ use Test::More;
-use strict; +use strict;
use warnings;
BEGIN { plan tests => 2 };
BEGIN { $ENV{PERL_JSON_BACKEND} = 0; }
diff --git a/cpan/JSON-PP/t/106_allow_barekey.t b/cpan/JSON-PP/t/106_allow_barekey.t index 20918bbdc2..f5c9189346 100644 --- a/cpan/JSON-PP/t/106_allow_barekey.t +++ b/cpan/JSON-PP/t/106_allow_barekey.t @@ -1,6 +1,6 @@ use Test::More;
-use strict; +use strict;
use warnings;
BEGIN { plan tests => 2 };
BEGIN { $ENV{PERL_JSON_BACKEND} = 0; }
diff --git a/cpan/JSON-PP/t/107_allow_singlequote.t b/cpan/JSON-PP/t/107_allow_singlequote.t index b3462f9775..5948f41841 100644 --- a/cpan/JSON-PP/t/107_allow_singlequote.t +++ b/cpan/JSON-PP/t/107_allow_singlequote.t @@ -1,6 +1,6 @@ use Test::More;
-use strict; +use strict;
use warnings;
BEGIN { plan tests => 4 };
BEGIN { $ENV{PERL_JSON_BACKEND} = 0; }
diff --git a/cpan/Math-BigInt/lib/Math/BigFloat.pm b/cpan/Math-BigInt/lib/Math/BigFloat.pm index b6d0bcbaf0..4a7a3f2e92 100644 --- a/cpan/Math-BigInt/lib/Math/BigFloat.pm +++ b/cpan/Math-BigInt/lib/Math/BigFloat.pm @@ -20,7 +20,7 @@ use Carp qw< carp croak >; use Scalar::Util qw< blessed >; use Math::BigInt qw< >; -our $VERSION = '1.999827'; +our $VERSION = '1.999828'; require Exporter; our @ISA = qw/Math::BigInt/; @@ -2194,71 +2194,81 @@ sub bpow { ($class, $x, $y, $a, $p, $r) = objectify(2, @_); } - return $x if $x->modify('bpow'); + return $x if $x -> modify('bpow'); # $x and/or $y is a NaN - return $x->bnan() if $x->is_nan() || $y->is_nan(); + return $x -> bnan() if $x -> is_nan() || $y -> is_nan(); # $x and/or $y is a +/-Inf - if ($x->is_inf("-")) { - return $x->bzero() if $y->is_negative(); - return $x->bnan() if $y->is_zero(); - return $x if $y->is_odd(); - return $x->bneg(); - } elsif ($x->is_inf("+")) { - return $x->bzero() if $y->is_negative(); - return $x->bnan() if $y->is_zero(); + if ($x -> is_inf("-")) { + return $x -> bzero() if $y -> is_negative(); + return $x -> bnan() if $y -> is_zero(); + return $x if $y -> is_odd(); + return $x -> bneg(); + } elsif ($x -> is_inf("+")) { + return $x -> bzero() if $y -> is_negative(); + return $x -> bnan() if $y -> is_zero(); + return $x; + } elsif ($y -> is_inf("-")) { + return $x -> bnan() if $x -> is_one("-"); + return $x -> binf("+") if $x > -1 && $x < 1; + return $x -> bone() if $x -> is_one("+"); + return $x -> bzero(); + } elsif ($y -> is_inf("+")) { + return $x -> bnan() if $x -> is_one("-"); + return $x -> bzero() if $x > -1 && $x < 1; + return $x -> bone() if $x -> is_one("+"); + return $x -> binf("+"); + } + + if ($x -> is_zero()) { + return $x -> bone() if $y -> is_zero(); + return $x -> binf() if $y -> is_negative(); return $x; - } elsif ($y->is_inf("-")) { - return $x->bnan() if $x -> is_one("-"); - return $x->binf("+") if $x > -1 && $x < 1; - return $x->bone() if $x -> is_one("+"); - return $x->bzero(); - } elsif ($y->is_inf("+")) { - return $x->bnan() if $x -> is_one("-"); - return $x->bzero() if $x > -1 && $x < 1; - return $x->bone() if $x -> is_one("+"); - return $x->binf("+"); } - # we don't support complex numbers, so return NaN - return $x->bnan() if $x->is_negative() && !$y->is_int(); - - # cache the result of is_zero - my $y_is_zero = $y->is_zero(); - return $x->bone() if $y_is_zero; - return $x if $x->is_one() || $y->is_one(); + # We don't support complex numbers, so upgrade or return NaN. - my $x_is_zero = $x->is_zero(); - return $x->_pow($y, $a, $p, $r) if !$x_is_zero && !$y->is_int(); - - my $y1 = $y->as_number()->{value}; # make MBI part + if ($x -> is_negative() && !$y -> is_int()) { + return $upgrade -> bpow($upgrade -> new($x), $y, $a, $p, $r) + if defined $upgrade; + return $x -> bnan(); + } - if ($x->is_one("-")) { - # if $x == -1 and odd/even y => +1/-1 because +-1 ^ (+-1) => +-1 - return $LIB->_is_odd($y1) ? $x : $x->babs(1); + if ($x -> is_one("+") || $y -> is_one()) { + return $x; } - if ($x_is_zero) { - return $x if $y->{sign} eq '+'; # 0**y => 0 (if not y <= 0) - # 0 ** -y => 1 / (0 ** y) => 1 / 0! (1 / 0 => +inf) - return $x->binf(); + + if ($x -> is_one("-")) { + return $x if $y -> is_odd(); + return $x -> bneg(); } + return $x -> _pow($y, $a, $p, $r) if !$y -> is_int(); + + my $y1 = $y -> as_int()->{value}; # make MBI part + my $new_sign = '+'; - $new_sign = $LIB->_is_odd($y1) ? '-' : '+' if $x->{sign} ne '+'; + $new_sign = $LIB -> _is_odd($y1) ? '-' : '+' if $x->{sign} ne '+'; # calculate $x->{_m} ** $y and $x->{_e} * $y separately (faster) - $x->{_m} = $LIB->_pow($x->{_m}, $y1); - $x->{_e} = $LIB->_mul ($x->{_e}, $y1); + $x->{_m} = $LIB -> _pow($x->{_m}, $y1); + $x->{_e} = $LIB -> _mul($x->{_e}, $y1); $x->{sign} = $new_sign; - $x->bnorm(); + $x -> bnorm(); + + # x ** (-y) = 1 / (x ** y) + if ($y->{sign} eq '-') { # modify $x in place! - my $z = $x->copy(); $x->bone(); - return scalar $x->bdiv($z, $a, $p, $r); # round in one go (might ignore y's A!) + my $z = $x -> copy(); + $x -> bone(); + # round in one go (might ignore y's A!) + return scalar $x -> bdiv($z, $a, $p, $r); } - $x->round($a, $p, $r, $y); + + $x -> round($a, $p, $r, $y); } sub blog { @@ -4071,6 +4081,94 @@ sub dparts { return ($int, $frc); } +sub fparts { + my $x = shift; + my $class = ref $x; + + croak("fparts() is an instance method") unless $class; + + return ($class -> bnan(), + $class -> bnan()) if $x -> is_nan(); + + return ($class -> binf($x -> sign()), + $class -> bone()) if $x -> is_inf(); + + return ($class -> bzero(), + $class -> bone()) if $x -> is_zero(); + + if ($x -> {_es} eq '-') { # exponent < 0 + my $numer_lib = $LIB -> _copy($x -> {_m}); + my $denom_lib = $LIB -> _1ex($x -> {_e}); + my $gcd_lib = $LIB -> _gcd($LIB -> _copy($numer_lib), $denom_lib); + $numer_lib = $LIB -> _div($numer_lib, $gcd_lib); + $denom_lib = $LIB -> _div($denom_lib, $gcd_lib); + return ($class -> new($x -> {sign} . $LIB -> _str($numer_lib)), + $class -> new($LIB -> _str($denom_lib))); + } + + elsif (! $LIB -> _is_zero($x -> {_e})) { # exponent > 0 + my $numer_lib = $LIB -> _copy($x -> {_m}); + $numer_lib = $LIB -> _lsft($numer_lib, $x -> {_e}, 10); + return ($class -> new($x -> {sign} . $LIB -> _str($numer_lib)), + $class -> bone()); + } + + else { # exponent = 0 + return ($class -> new($x -> {sign} . $LIB -> _str($x -> {_m})), + $class -> bone()); + } +} + +sub numerator { + my $x = shift; + my $class = ref $x; + + croak("numerator() is an instance method") unless $class; + + return $class -> bnan() if $x -> is_nan(); + return $class -> binf($x -> sign()) if $x -> is_inf(); + return $class -> bzero() if $x -> is_zero(); + + if ($x -> {_es} eq '-') { # exponent < 0 + my $numer_lib = $LIB -> _copy($x -> {_m}); + my $denom_lib = $LIB -> _1ex($x -> {_e}); + my $gcd_lib = $LIB -> _gcd($LIB -> _copy($numer_lib), $denom_lib); + $numer_lib = $LIB -> _div($numer_lib, $gcd_lib); + return $class -> new($x -> {sign} . $LIB -> _str($numer_lib)); + } + + elsif (! $LIB -> _is_zero($x -> {_e})) { # exponent > 0 + my $numer_lib = $LIB -> _copy($x -> {_m}); + $numer_lib = $LIB -> _lsft($numer_lib, $x -> {_e}, 10); + return $class -> new($x -> {sign} . $LIB -> _str($numer_lib)); + } + + else { # exponent = 0 + return $class -> new($x -> {sign} . $LIB -> _str($x -> {_m})); + } +} + +sub denominator { + my $x = shift; + my $class = ref $x; + + croak("denominator() is an instance method") unless $class; + + return $class -> bnan() if $x -> is_nan(); + + if ($x -> {_es} eq '-') { # exponent < 0 + my $numer_lib = $LIB -> _copy($x -> {_m}); + my $denom_lib = $LIB -> _1ex($x -> {_e}); + my $gcd_lib = $LIB -> _gcd($LIB -> _copy($numer_lib), $denom_lib); + $denom_lib = $LIB -> _div($denom_lib, $gcd_lib); + return $class -> new($LIB -> _str($denom_lib)); + } + + else { # exponent >= 0 + return $class -> bone(); + } +} + ############################################################################### # String conversion methods ############################################################################### @@ -4412,7 +4510,7 @@ sub to_ieee754 { $mant -> bmul($b -> copy() -> bpow($expo_abs)); } - # Final adjustment. + # Final adjustment of the estimate above. while ($mant >= $b && $expo <= $emax) { $mant -> bmul($binv); @@ -4424,19 +4522,63 @@ sub to_ieee754 { $expo -> bdec(); } - # Encode as infinity, normal number or subnormal number? + # This is when the magnitude is larger than what can be represented + # in this format. Encode as infinity. - if ($expo > $emax) { # overflow => infinity - $expo = $emax -> copy() -> binc(); + if ($expo > $emax) { $mant = $class -> bzero(); - } elsif ($expo < $emin) { # subnormal number - my $const = $class -> new(2) -> bpow($t - 1); + $expo = $emax -> copy() -> binc(); + } + + # This is when the magnitude is so small that the number is encoded + # as a subnormal number. + # + # If the magnitude is smaller than that of the smallest subnormal + # number, and rounded downwards, it is encoded as zero. This works + # transparently and does not need to be treated as a special case. + # + # If the number is between the largest subnormal number and the + # smallest normal number, and the value is rounded upwards, the + # value must be encoded as a normal number. This must be treated as + # a special case. + + elsif ($expo < $emin) { + + # Scale up the mantissa (significand), and round to integer. + + my $const = $class -> new($b) -> bpow($t - 1); $mant -> bmul($const); $mant -> bfround(0); - } else { # normal number - $mant -> bdec(); # remove implicit leading bit - my $const = $class -> new(2) -> bpow($t); + + # If the mantissa overflowed, encode as the smallest normal + # number. + + if ($mant == $const -> bmul($b)) { + $mant -> bzero(); + $expo -> binc(); + } + } + + # This is when the magnitude is within the range of what can be + # encoded as a normal number. + + else { + + # Remove implicit leading bit, scale up the mantissa + # (significand) to an integer, and round. + + $mant -> bdec(); + my $const = $class -> new($b) -> bpow($t); $mant -> bmul($const) -> bfround(0); + + # If the mantissa overflowed, encode as the next larger value. + # This works correctly also when the next larger value is + # infinity. + + if ($mant == $const) { + $mant -> bzero(); + $expo -> binc(); + } } } @@ -5246,6 +5388,9 @@ Math::BigFloat - Arbitrary size floating point math package $x->nparts(); # mantissa and exponent (normalised) $x->eparts(); # mantissa and exponent (engineering notation) $x->dparts(); # integer and fraction part + $x->fparts(); # numerator and denominator + $x->numerator(); # numerator + $x->denominator(); # denominator # Conversion methods (do not modify the invocand) diff --git a/cpan/Math-BigInt/lib/Math/BigInt.pm b/cpan/Math-BigInt/lib/Math/BigInt.pm index 84c4bcdcf4..d02b7b78b8 100644 --- a/cpan/Math-BigInt/lib/Math/BigInt.pm +++ b/cpan/Math-BigInt/lib/Math/BigInt.pm @@ -23,7 +23,7 @@ use warnings; use Carp qw< carp croak >; use Scalar::Util qw< blessed >; -our $VERSION = '1.999827'; +our $VERSION = '1.999828'; require Exporter; our @ISA = qw(Exporter); @@ -2430,47 +2430,63 @@ sub bpow { ($class, $x, $y, @r) = objectify(2, @_); } - return $x if $x->modify('bpow'); + return $x if $x -> modify('bpow'); # $x and/or $y is a NaN - return $x->bnan() if $x->is_nan() || $y->is_nan(); + return $x -> bnan() if $x -> is_nan() || $y -> is_nan(); # $x and/or $y is a +/-Inf - if ($x->is_inf("-")) { - return $x->bzero() if $y->is_negative(); - return $x->bnan() if $y->is_zero(); - return $x if $y->is_odd(); - return $x->bneg(); - } elsif ($x->is_inf("+")) { - return $x->bzero() if $y->is_negative(); - return $x->bnan() if $y->is_zero(); + if ($x -> is_inf("-")) { + return $x -> bzero() if $y -> is_negative(); + return $x -> bnan() if $y -> is_zero(); + return $x if $y -> is_odd(); + return $x -> bneg(); + } elsif ($x -> is_inf("+")) { + return $x -> bzero() if $y -> is_negative(); + return $x -> bnan() if $y -> is_zero(); + return $x; + } elsif ($y -> is_inf("-")) { + return $x -> bnan() if $x -> is_one("-"); + return $x -> binf("+") if $x -> is_zero(); + return $x -> bone() if $x -> is_one("+"); + return $x -> bzero(); + } elsif ($y -> is_inf("+")) { + return $x -> bnan() if $x -> is_one("-"); + return $x -> bzero() if $x -> is_zero(); + return $x -> bone() if $x -> is_one("+"); + return $x -> binf("+"); + } + + if ($x -> is_zero()) { + return $x -> bone() if $y -> is_zero(); + return $x -> binf() if $y -> is_negative(); return $x; - } elsif ($y->is_inf("-")) { - return $x->bnan() if $x -> is_one("-"); - return $x->binf("+") if $x -> is_zero(); - return $x->bone() if $x -> is_one("+"); - return $x->bzero(); - } elsif ($y->is_inf("+")) { - return $x->bnan() if $x -> is_one("-"); - return $x->bzero() if $x -> is_zero(); - return $x->bone() if $x -> is_one("+"); - return $x->binf("+"); } - return $upgrade->bpow($upgrade->new($x), $y, @r) - if defined $upgrade && (!$y->isa($class) || $y->{sign} eq '-'); + if ($x -> is_one("+")) { + return $x; + } - $r[3] = $y; # no push! + if ($x -> is_one("-")) { + return $x if $y -> is_odd(); + return $x -> bneg(); + } - # 0 ** -y => ( 1 / (0 ** y)) => 1 / 0 => +inf - return $x->binf() if $y->is_negative() && $x->is_zero(); + # We don't support finite non-integers, so upgrade or return zero. The + # reason for returning zero, not NaN, is that all output is in the open + # interval (0,1), and truncating that to integer gives zero. - # 1 ** -y => 1 / (1 ** |y|) - return $x->bzero() if $y->is_negative() && !$LIB->_is_one($x->{value}); + if ($y->{sign} eq '-' || !$y -> isa($class)) { + return $upgrade -> bpow($upgrade -> new($x), $y, @r) + if defined $upgrade; + return $x -> bzero(); + } - $x->{value} = $LIB->_pow($x->{value}, $y->{value}); - $x->{sign} = $x->is_negative() && $y->is_odd() ? '-' : '+'; - $x->round(@r); + $r[3] = $y; # no push! + + $x->{value} = $LIB -> _pow($x->{value}, $y->{value}); + $x->{sign} = $x -> is_negative() && $y -> is_odd() ? '-' : '+'; + $x -> round(@r); } sub blog { @@ -3792,6 +3808,34 @@ sub dparts { return ($int, $frc); } +sub fparts { + my $x = shift; + my $class = ref $x; + + croak("fparts() is an instance method") unless $class; + + return ($x -> copy(), + $x -> is_nan() ? $class -> bnan() : $class -> bone()); +} + +sub numerator { + my $x = shift; + my $class = ref $x; + + croak("numerator() is an instance method") unless $class; + + return $x -> copy(); +} + +sub denominator { + my $x = shift; + my $class = ref $x; + + croak("denominator() is an instance method") unless $class; + + return $x -> is_nan() ? $class -> bnan() : $class -> bone(); +} + ############################################################################### # String conversion methods ############################################################################### @@ -4402,7 +4446,7 @@ sub import { if (@a) { $class->SUPER::import(@a); # need it for subclasses - $class->export_to_level(1, $class, @a); # need it for Math::BigFlaot + $class->export_to_level(1, $class, @a); # need it for Math::BigFloat } # We might not have loaded any backend library yet, either because the user @@ -5435,6 +5479,9 @@ Math::BigInt - Arbitrary size integer/float math package $x->nparts(); # mantissa and exponent (normalised) $x->eparts(); # mantissa and exponent (engineering notation) $x->dparts(); # integer and fraction part + $x->fparts(); # numerator and denominator + $x->numerator(); # numerator + $x->denominator(); # denominator # Conversion methods (do not modify the invocand) @@ -6746,6 +6793,24 @@ Returns the integer part and the fraction part. If the fraction part can not be represented as an integer, upgrading is performed or NaN is returned. The output of C<dparts()> corresponds to the output from C<bdstr()>. +=item fparts() + +Returns the smallest possible numerator and denominator so that the numerator +divided by the denominator gives back the original value. For finite numbers, +both values are integers. Mnemonic: fraction. + +=item numerator() + +Together with L</denominator()>, returns the smallest integers so that the +numerator divided by the denominator reproduces the original value. With +Math::BigInt, numerator() simply returns a copy of the invocand. + +=item denominator() + +Together with L</numerator()>, returns the smallest integers so that the +numerator divided by the denominator reproduces the original value. With +Math::BigInt, denominator() always returns either a 1 or a NaN. + =back =head2 String conversion methods @@ -7182,7 +7247,7 @@ This is how it works now: * You can also set P globally by using Math::SomeClass->precision() likewise. * Globals are classwide, and not inherited by subclasses. - * to undefine A, use Math::SomeCLass->accuracy(undef); + * to undefine A, use Math::SomeClass->accuracy(undef); * to undefine P, use Math::SomeClass->precision(undef); * Setting Math::SomeClass->accuracy() clears automatically Math::SomeClass->precision(), and vice versa. @@ -7217,8 +7282,8 @@ This is how it works now: use Math::BigInt; Math::BigInt->accuracy(2); - Math::BigInt::SomeSubClass->accuracy(3); - $x = Math::BigInt::SomeSubClass->new(1234); + Math::BigInt::SomeSubclass->accuracy(3); + $x = Math::BigInt::SomeSubclass->new(1234); $x is now 1230, and not 1200. A subclass might choose to implement this otherwise, e.g. falling back to the parent's A and P. @@ -7480,7 +7545,7 @@ when dividing any negative number by 0. $x = Math::BigInt->babs("-12345"); # Math::BigInt "12345" $x = Math::BigInt->bnorm("-0.00"); # Math::BigInt "0" $x = bigint(1) + bigint(2); # Math::BigInt "3" - $x = bigint(1) + "2"; # ditto (auto-Math::BigIntify of "2") + $x = bigint(1) + "2"; # ditto ("2" becomes a Math::BigInt) $x = bigint(1); # Math::BigInt "1" $x = $x + 5 / 2; # Math::BigInt "3" $x = $x ** 3; # Math::BigInt "27" diff --git a/cpan/Math-BigInt/lib/Math/BigInt/Calc.pm b/cpan/Math-BigInt/lib/Math/BigInt/Calc.pm index 1269f644bf..eaeda41f32 100644 --- a/cpan/Math-BigInt/lib/Math/BigInt/Calc.pm +++ b/cpan/Math-BigInt/lib/Math/BigInt/Calc.pm @@ -7,7 +7,7 @@ use warnings; use Carp qw< carp croak >; use Math::BigInt::Lib; -our $VERSION = '1.999827'; +our $VERSION = '1.999828'; our @ISA = ('Math::BigInt::Lib'); diff --git a/cpan/Math-BigInt/lib/Math/BigInt/Lib.pm b/cpan/Math-BigInt/lib/Math/BigInt/Lib.pm index ac570af3f1..5b6043c561 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.999827'; +our $VERSION = '1.999828'; use Carp; @@ -2013,8 +2013,8 @@ Math::BigInt::Lib - virtual parent class for Math::BigInt libraries package Math::BigInt::MyBackend; - use Math::BigInt::lib; - our @ISA = qw< Math::BigInt::lib >; + use Math::BigInt::Lib; + our @ISA = qw< Math::BigInt::Lib >; sub _new { ... } sub _str { ... } diff --git a/cpan/Math-BigInt/t/bpow-mbf.t b/cpan/Math-BigInt/t/bpow-mbf.t new file mode 100644 index 0000000000..72ad4d9c21 --- /dev/null +++ b/cpan/Math-BigInt/t/bpow-mbf.t @@ -0,0 +1,348 @@ +# -*- mode: perl; -*- + +use strict; +use warnings; + +use Test::More tests => 255; + +use Math::BigFloat; + +my $class = "Math::BigFloat"; + +use Math::Complex (); + +my $inf = $Math::Complex::Inf; +my $nan = $inf - $inf; + +# The following is used to compute the data at the end of this file. + +if (0) { + my @x = (-$inf, -64, -3, -2.5, -2, -1.5, -1, -0.5, 0, + 0.5, 1, 1.5, 2, 2.5, 3, 64, $inf); + my @y = (-$inf, -3, -2.5, -2, -1.5, -1, -0.5, 0, + 0.5, 1, 1.5, 2, 2.5, 3, $inf); + for my $x (@x) { + for my $y (@y) { + + # The exceptions here are based on Wolfram Alpha, + # https://www.wolframalpha.com/ + + my $z = $x == -$inf && $y == 0 ? $nan + : $x == $inf && $y == 0 ? $nan + : $x == -1 && $y == -$inf ? $nan + : $x == -1 && $y == $inf ? $nan + : $x ** $y; + + # Unfortunately, Math::Big* uses "inf", not "Inf" as Perl. + + printf "%s\n", join ":", map { $_ == $inf ? "inf" + : $_ == -$inf ? "-inf" + : $_ } $x, $y, $z; + } + } + + exit; +} + +while (<DATA>) { + s/#.*$//; # remove comments + s/\s+$//; # remove trailing whitespace + next unless length; # skip empty lines + + my @args = split /:/; + my $want = pop @args; + + my ($x, $y, $z); + + my $test = qq|\$x = $class -> new("$args[0]"); | + . qq|\$y = $class -> new("$args[1]"); | + . qq|\$z = \$x -> bpow(\$y)|; + + eval "$test"; + die $@ if $@; + + subtest $test => sub { + plan tests => 5; + + is(ref($x), $class, "\$x is still a $class"); + + is(ref($y), $class, "\$y is still a $class"); + is($y, $args[1], "\$y is unmodified"); + + is(ref($z), $class, "\$z is a $class"); + + # If $want is a finite non-integer and $x is finite, measure the + # relative difference. + + if ($want * 0 == 0 && $want != int $want && $x -> is_finite()) { + if (abs(($z -> numify() - $want) / $want) < 1e-8) { + pass("\$z has the right value"); + } else { + fail("\$z has the right value"); + diag(<<"EOF"); + got: '$z' + expected: '$want' +EOF + } + } else { + is($z, $want, "\$z has the right value"); + } + }; +} + +__END__ +-inf:-inf:0 +-inf:-3:0 +-inf:-2.5:0 +-inf:-2:0 +-inf:-1.5:0 +-inf:-1:0 +-inf:-0.5:0 +-inf:0:NaN +-inf:0.5:inf +-inf:1:-inf +-inf:1.5:inf +-inf:2:inf +-inf:2.5:inf +-inf:3:-inf +-inf:inf:inf +-64:-inf:0 +-64:-3:-3.814697265625e-06 +-64:-2.5:NaN +-64:-2:0.000244140625 +-64:-1.5:NaN +-64:-1:-0.015625 +-64:-0.5:NaN +-64:0:1 +-64:0.5:NaN +-64:1:-64 +-64:1.5:NaN +-64:2:4096 +-64:2.5:NaN +-64:3:-262144 +-64:inf:inf +-3:-inf:0 +-3:-3:-0.037037037037037 +-3:-2.5:NaN +-3:-2:0.111111111111111 +-3:-1.5:NaN +-3:-1:-0.333333333333333 +-3:-0.5:NaN +-3:0:1 +-3:0.5:NaN +-3:1:-3 +-3:1.5:NaN +-3:2:9 +-3:2.5:NaN +-3:3:-27 +-3:inf:inf +-2.5:-inf:0 +-2.5:-3:-0.064 +-2.5:-2.5:NaN +-2.5:-2:0.16 +-2.5:-1.5:NaN +-2.5:-1:-0.4 +-2.5:-0.5:NaN +-2.5:0:1 +-2.5:0.5:NaN +-2.5:1:-2.5 +-2.5:1.5:NaN +-2.5:2:6.25 +-2.5:2.5:NaN +-2.5:3:-15.625 +-2.5:inf:inf +-2:-inf:0 +-2:-3:-0.125 +-2:-2.5:NaN +-2:-2:0.25 +-2:-1.5:NaN +-2:-1:-0.5 +-2:-0.5:NaN +-2:0:1 +-2:0.5:NaN +-2:1:-2 +-2:1.5:NaN +-2:2:4 +-2:2.5:NaN +-2:3:-8 +-2:inf:inf +-1.5:-inf:0 +-1.5:-3:-0.296296296296296 +-1.5:-2.5:NaN +-1.5:-2:0.444444444444444 +-1.5:-1.5:NaN +-1.5:-1:-0.666666666666667 +-1.5:-0.5:NaN +-1.5:0:1 +-1.5:0.5:NaN +-1.5:1:-1.5 +-1.5:1.5:NaN +-1.5:2:2.25 +-1.5:2.5:NaN +-1.5:3:-3.375 +-1.5:inf:inf +-1:-inf:NaN +-1:-3:-1 +-1:-2.5:NaN +-1:-2:1 +-1:-1.5:NaN +-1:-1:-1 +-1:-0.5:NaN +-1:0:1 +-1:0.5:NaN +-1:1:-1 +-1:1.5:NaN +-1:2:1 +-1:2.5:NaN +-1:3:-1 +-1:inf:NaN +-0.5:-inf:inf +-0.5:-3:-8 +-0.5:-2.5:NaN +-0.5:-2:4 +-0.5:-1.5:NaN +-0.5:-1:-2 +-0.5:-0.5:NaN +-0.5:0:1 +-0.5:0.5:NaN +-0.5:1:-0.5 +-0.5:1.5:NaN +-0.5:2:0.25 +-0.5:2.5:NaN +-0.5:3:-0.125 +-0.5:inf:0 +0:-inf:inf +0:-3:inf +0:-2.5:inf +0:-2:inf +0:-1.5:inf +0:-1:inf +0:-0.5:inf +0:0:1 +0:0.5:0 +0:1:0 +0:1.5:0 +0:2:0 +0:2.5:0 +0:3:0 +0:inf:0 +0.5:-inf:inf +0.5:-3:8 +0.5:-2.5:5.65685424949238 +0.5:-2:4 +0.5:-1.5:2.82842712474619 +0.5:-1:2 +0.5:-0.5:1.4142135623731 +0.5:0:1 +0.5:0.5:0.707106781186548 +0.5:1:0.5 +0.5:1.5:0.353553390593274 +0.5:2:0.25 +0.5:2.5:0.176776695296637 +0.5:3:0.125 +0.5:inf:0 +1:-inf:1 +1:-3:1 +1:-2.5:1 +1:-2:1 +1:-1.5:1 +1:-1:1 +1:-0.5:1 +1:0:1 +1:0.5:1 +1:1:1 +1:1.5:1 +1:2:1 +1:2.5:1 +1:3:1 +1:inf:1 +1.5:-inf:0 +1.5:-3:0.296296296296296 +1.5:-2.5:0.362887369301212 +1.5:-2:0.444444444444444 +1.5:-1.5:0.544331053951817 +1.5:-1:0.666666666666667 +1.5:-0.5:0.816496580927726 +1.5:0:1 +1.5:0.5:1.22474487139159 +1.5:1:1.5 +1.5:1.5:1.83711730708738 +1.5:2:2.25 +1.5:2.5:2.75567596063108 +1.5:3:3.375 +1.5:inf:inf +2:-inf:0 +2:-3:0.125 +2:-2.5:0.176776695296637 +2:-2:0.25 +2:-1.5:0.353553390593274 +2:-1:0.5 +2:-0.5:0.707106781186548 +2:0:1 +2:0.5:1.4142135623731 +2:1:2 +2:1.5:2.82842712474619 +2:2:4 +2:2.5:5.65685424949238 +2:3:8 +2:inf:inf +2.5:-inf:0 +2.5:-3:0.064 +2.5:-2.5:0.101192885125388 +2.5:-2:0.16 +2.5:-1.5:0.25298221281347 +2.5:-1:0.4 +2.5:-0.5:0.632455532033676 +2.5:0:1 +2.5:0.5:1.58113883008419 +2.5:1:2.5 +2.5:1.5:3.95284707521047 +2.5:2:6.25 +2.5:2.5:9.88211768802619 +2.5:3:15.625 +2.5:inf:inf +3:-inf:0 +3:-3:0.037037037037037 +3:-2.5:0.0641500299099584 +3:-2:0.111111111111111 +3:-1.5:0.192450089729875 +3:-1:0.333333333333333 +3:-0.5:0.577350269189626 +3:0:1 +3:0.5:1.73205080756888 +3:1:3 +3:1.5:5.19615242270663 +3:2:9 +3:2.5:15.5884572681199 +3:3:27 +3:inf:inf +64:-inf:0 +64:-3:3.814697265625e-06 +64:-2.5:3.0517578125e-05 +64:-2:0.000244140625 +64:-1.5:0.001953125 +64:-1:0.015625 +64:-0.5:0.125 +64:0:1 +64:0.5:8 +64:1:64 +64:1.5:512 +64:2:4096 +64:2.5:32768 +64:3:262144 +64:inf:inf +inf:-inf:0 +inf:-3:0 +inf:-2.5:0 +inf:-2:0 +inf:-1.5:0 +inf:-1:0 +inf:-0.5:0 +inf:0:NaN +inf:0.5:inf +inf:1:inf +inf:1.5:inf +inf:2:inf +inf:2.5:inf +inf:3:inf +inf:inf:inf diff --git a/cpan/Math-BigInt/t/bpow-mbi.t b/cpan/Math-BigInt/t/bpow-mbi.t new file mode 100644 index 0000000000..6fbf270821 --- /dev/null +++ b/cpan/Math-BigInt/t/bpow-mbi.t @@ -0,0 +1,172 @@ +# -*- mode: perl; -*- + +use strict; +use warnings; + +use Test::More tests => 99; + +use Math::BigInt; + +my $class = "Math::BigInt"; + +use Math::Complex (); + +my $inf = $Math::Complex::Inf; +my $nan = $inf - $inf; + +# The following is used to compute the data at the end of this file. + +if (0) { + for my $x (-$inf, -64, -3, -2, -1, 0, 1, 2, 3, 64, $inf) { + for my $y (-$inf, -3, -2, -1, 0, 1, 2, 3, $inf) { + + # The exceptions here are based on Wolfram Alpha, + # https://www.wolframalpha.com/ + + my $z = $x == -$inf && $y == 0 ? $nan + : $x == $inf && $y == 0 ? $nan + : $x == -1 && $y == -$inf ? $nan + : $x == -1 && $y == $inf ? $nan + : int($x ** $y); + + # Unfortunately, Math::Big* uses "inf", not "Inf" as Perl. + + printf "%s\n", join ":", map { $_ == $inf ? "inf" + : $_ == -$inf ? "-inf" + : $_ } $x, $y, $z; + } + } + + exit; +} + +while (<DATA>) { + s/#.*$//; # remove comments + s/\s+$//; # remove trailing whitespace + next unless length; # skip empty lines + + my @args = split /:/; + my $want = pop @args; + + my ($x, $y, $z); + + my $test = qq|\$x = $class -> new("$args[0]"); | + . qq|\$y = $class -> new("$args[1]"); | + . qq|\$z = \$x -> bpow(\$y)|; + + eval "$test"; + die $@ if $@; + + subtest $test => sub { + plan tests => 5; + + is(ref($x), $class, "\$x is still a $class"); + + is(ref($y), $class, "\$y is still a $class"); + is($y, $args[1], "\$y is unmodified"); + + is(ref($z), $class, "\$z is a $class"); + is($z, $want, "\$z has the right value"); + }; +} + +__DATA__ +-inf:-inf:0 +-inf:-3:0 +-inf:-2:0 +-inf:-1:0 +-inf:0:NaN +-inf:1:-inf +-inf:2:inf +-inf:3:-inf +-inf:inf:inf +-64:-inf:0 +-64:-3:0 +-64:-2:0 +-64:-1:0 +-64:0:1 +-64:1:-64 +-64:2:4096 +-64:3:-262144 +-64:inf:inf +-3:-inf:0 +-3:-3:0 +-3:-2:0 +-3:-1:0 +-3:0:1 +-3:1:-3 +-3:2:9 +-3:3:-27 +-3:inf:inf +-2:-inf:0 +-2:-3:0 +-2:-2:0 +-2:-1:0 +-2:0:1 +-2:1:-2 +-2:2:4 +-2:3:-8 +-2:inf:inf +-1:-inf:NaN +-1:-3:-1 +-1:-2:1 +-1:-1:-1 +-1:0:1 +-1:1:-1 +-1:2:1 +-1:3:-1 +-1:inf:NaN +0:-inf:inf +0:-3:inf +0:-2:inf +0:-1:inf +0:0:1 +0:1:0 +0:2:0 +0:3:0 +0:inf:0 +1:-inf:1 +1:-3:1 +1:-2:1 +1:-1:1 +1:0:1 +1:1:1 +1:2:1 +1:3:1 +1:inf:1 +2:-inf:0 +2:-3:0 +2:-2:0 +2:-1:0 +2:0:1 +2:1:2 +2:2:4 +2:3:8 +2:inf:inf +3:-inf:0 +3:-3:0 +3:-2:0 +3:-1:0 +3:0:1 +3:1:3 +3:2:9 +3:3:27 +3:inf:inf +64:-inf:0 +64:-3:0 +64:-2:0 +64:-1:0 +64:0:1 +64:1:64 +64:2:4096 +64:3:262144 +64:inf:inf +inf:-inf:0 +inf:-3:0 +inf:-2:0 +inf:-1:0 +inf:0:NaN +inf:1:inf +inf:2:inf +inf:3:inf +inf:inf:inf diff --git a/cpan/Math-BigInt/t/fparts-mbf.t b/cpan/Math-BigInt/t/fparts-mbf.t new file mode 100644 index 0000000000..8d555bde9c --- /dev/null +++ b/cpan/Math-BigInt/t/fparts-mbf.t @@ -0,0 +1,97 @@ +# -*- mode: perl; -*- + +# test fparts(), numerator(), denominator() + +use strict; +use warnings; + +use Test::More tests => 43; + +my $class; + +BEGIN { + $class = 'Math::BigFloat'; + use_ok($class); +} + +while (<DATA>) { + s/#.*$//; # remove comments + s/\s+$//; # remove trailing whitespace + next unless length; # skip empty lines + + my ($x_str, $n_str, $d_str) = split /:/; + my $test; + + # test fparts() + + $test = qq|\$x = $class -> new("$x_str");| + . qq| (\$n, \$d) = \$x -> fparts();|; + + subtest $test => sub { + plan tests => 5; + + my $x = $class -> new($x_str); + my ($n, $d) = $x -> fparts(); + + is(ref($n), $class, "class of numerator"); + is(ref($d), $class, "class of denominator"); + + is($n, $n_str, "value of numerator"); + is($d, $d_str, "value of denominator"); + is($x, $x_str, "input is unmodified"); + }; + + # test numerator() + + $test = qq|\$x = $class -> new("$x_str");| + . qq| \$n = \$x -> numerator();|; + + subtest $test => sub { + plan tests => 3; + + my $x = $class -> new($x_str); + my $n = $x -> numerator(); + + is(ref($n), $class, "class of numerator"); + + is($n, $n_str, "value of numerator"); + is($x, $x_str, "input is unmodified"); + }; + + # test denominator() + + $test = qq|\$x = $class -> new("$x_str");| + . qq| \$d = \$x -> denominator();|; + + subtest $test => sub { + plan tests => 3; + + my $x = $class -> new($x_str); + my $d = $x -> denominator(); + + is(ref($d), $class, "class of denominator"); + + is($d, $d_str, "value of denominator"); + is($x, $x_str, "input is unmodified"); + }; +} + +__DATA__ + +NaN:NaN:NaN + +inf:inf:1 +-inf:-inf:1 + +-30:-30:1 +-3:-3:1 +-1:-1:1 +0:0:1 +1:1:1 +3:3:1 +30:30:1 + +-31400:-31400:1 +-3.14:-157:50 +3.14:157:50 +31400:31400:1 diff --git a/cpan/Math-BigInt/t/fparts-mbi.t b/cpan/Math-BigInt/t/fparts-mbi.t new file mode 100644 index 0000000000..449d6d8a59 --- /dev/null +++ b/cpan/Math-BigInt/t/fparts-mbi.t @@ -0,0 +1,92 @@ +# -*- mode: perl; -*- + +# test fparts(), numerator(), denominator() + +use strict; +use warnings; + +use Test::More tests => 31; + +my $class; + +BEGIN { + $class = 'Math::BigInt'; + use_ok($class); +} + +while (<DATA>) { + s/#.*$//; # remove comments + s/\s+$//; # remove trailing whitespace + next unless length; # skip empty lines + + my ($x_str, $n_str, $d_str) = split /:/; + my $test; + + # test fparts() + + $test = qq|\$x = $class -> new("$x_str");| + . qq| (\$n, \$d) = \$x -> fparts();|; + + subtest $test => sub { + plan tests => 5; + + my $x = $class -> new($x_str); + my ($n, $d) = $x -> fparts(); + + is(ref($n), $class, "class of numerator"); + is(ref($d), $class, "class of denominator"); + + is($n, $n_str, "value of numerator"); + is($d, $d_str, "value of denominator"); + is($x, $x_str, "input is unmodified"); + }; + + # test numerator() + + $test = qq|\$x = $class -> new("$x_str");| + . qq| \$n = \$x -> numerator();|; + + subtest $test => sub { + plan tests => 3; + + my $x = $class -> new($x_str); + my $n = $x -> numerator(); + + is(ref($n), $class, "class of numerator"); + + is($n, $n_str, "value of numerator"); + is($x, $x_str, "input is unmodified"); + }; + + # test denominator() + + $test = qq|\$x = $class -> new("$x_str");| + . qq| \$d = \$x -> denominator();|; + + subtest $test => sub { + plan tests => 3; + + my $x = $class -> new($x_str); + my $d = $x -> denominator(); + + is(ref($d), $class, "class of denominator"); + + is($d, $d_str, "value of denominator"); + is($x, $x_str, "input is unmodified"); + }; +} + +__DATA__ + +NaN:NaN:NaN + +inf:inf:1 +-inf:-inf:1 + +-30:-30:1 +-3:-3:1 +-1:-1:1 +0:0:1 +1:1:1 +3:3:1 +30:30:1 diff --git a/cpan/Math-BigInt/t/isa.t b/cpan/Math-BigInt/t/isa.t index 984d048b98..366c12d09f 100644 --- a/cpan/Math-BigInt/t/isa.t +++ b/cpan/Math-BigInt/t/isa.t @@ -20,7 +20,7 @@ isa_ok($class->new(123), 'Math::BigInt'); # ditto for plain Math::BigInt isa_ok(Math::BigInt->new(123), 'Math::BigInt'); -# But Math::BigFloats aren't +# But Math::BigFloat objects aren't ok(!Math::BigFloat->new(123)->isa('Math::BigInt'), "A Math::BigFloat isn't a Math::BigInt"); diff --git a/cpan/Math-BigInt/t/to_ieee754-mbf.t b/cpan/Math-BigInt/t/to_ieee754-mbf.t index 7994b705a1..9dbfa092cb 100644 --- a/cpan/Math-BigInt/t/to_ieee754-mbf.t +++ b/cpan/Math-BigInt/t/to_ieee754-mbf.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 60; +use Test::More tests => 66; use Math::BigFloat; @@ -204,3 +204,100 @@ for my $k (@k) { is($got_hex, $expected_hex); } } + +# These tests verify fixing CPAN RT #139960. + +# binary16 + +{ + # largest subnormal number + my $lo = Math::BigFloat -> from_ieee754("03ff", "binary16"); + + # smallest normal number + my $hi = Math::BigFloat -> from_ieee754("0400", "binary16"); + + # compute an average weighted towards the larger of the two + my $x = 0.25 * $lo + 0.75 * $hi; + + my $got = unpack "H*", $x -> to_ieee754("binary16"); + is($got, "0400", + "6.102025508880615234375e-5 -> 0x0400"); +} + +{ + # largest number smaller than one + my $lo = Math::BigFloat -> from_ieee754("3bff", "binary16"); + + # one + my $hi = Math::BigFloat -> from_ieee754("3c00", "binary16"); + + # compute an average weighted towards the larger of the two + my $x = 0.25 * $lo + 0.75 * $hi; + + my $got = unpack "H*", $x -> to_ieee754("binary16"); + is($got, "3c00", "9.998779296875e-1 -> 0x3c00"); +} + +# binary32 + +{ + # largest subnormal number + my $lo = Math::BigFloat -> from_ieee754("007fffff", "binary32"); + + # smallest normal number + my $hi = Math::BigFloat -> from_ieee754("00800000", "binary32"); + + # compute an average weighted towards the larger of the two + my $x = 0.25 * $lo + 0.75 * $hi; + + my $got = unpack "H*", $x -> to_ieee754("binary32"); + is($got, "00800000", + "1.1754943157898258998483097641290060955707622747...e-38 -> 0x00800000"); +} + +{ + # largest number smaller than one + my $lo = Math::BigFloat -> from_ieee754("3f7fffff", "binary32"); + + # one + my $hi = Math::BigFloat -> from_ieee754("3f800000", "binary32"); + + # compute an average weighted towards the larger of the two + my $x = 0.25 * $lo + 0.75 * $hi; + + my $got = unpack "H*", $x -> to_ieee754("binary32"); + is($got, "3f800000", + "9.9999998509883880615234375e-1 -> 0x3f800000"); +} + +# binary64 + +{ + # largest subnormal number + my $lo = Math::BigFloat -> from_ieee754("000fffffffffffff", "binary64"); + + # smallest normal number + my $hi = Math::BigFloat -> from_ieee754("0010000000000000", "binary64"); + + # compute an average weighted towards the larger of the two + my $x = 0.25 * $lo + 0.75 * $hi; + + my $got = unpack "H*", $x -> to_ieee754("binary64"); + is($got, "0010000000000000", + "2.2250738585072012595738212570207680200...e-308 -> 0x0010000000000000"); +} + +{ + # largest number smaller than one + my $lo = Math::BigFloat -> from_ieee754("3fefffffffffffff", "binary64"); + + # one + my $hi = Math::BigFloat -> from_ieee754("3ff0000000000000", "binary64"); + + # compute an average weighted towards the larger of the two + my $x = 0.25 * $lo + 0.75 * $hi; + + my $got = unpack "H*", $x -> to_ieee754("binary64"); + is($got, "3ff0000000000000", + "9.999999999999999722444243843710864894092...e-1 -> 0x3ff0000000000000"); +} diff --git a/cpan/Math-BigInt/t/upgrade.inc b/cpan/Math-BigInt/t/upgrade.inc index ce5771eef3..3cef71108d 100644 --- a/cpan/Math-BigInt/t/upgrade.inc +++ b/cpan/Math-BigInt/t/upgrade.inc @@ -231,7 +231,7 @@ sub is_valid { my ($x, $f, $c) = @_; # The checks here are loosened a bit to allow Math::BigInt or - # Math::BigFloats to pass + # Math::BigFloat objects to pass my $e = 0; # error? |