summaryrefslogtreecommitdiff
path: root/cpan/Math-BigInt/lib/Math/BigFloat.pm
diff options
context:
space:
mode:
Diffstat (limited to 'cpan/Math-BigInt/lib/Math/BigFloat.pm')
-rw-r--r--cpan/Math-BigInt/lib/Math/BigFloat.pm259
1 files changed, 161 insertions, 98 deletions
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