New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Math::BigFloat and Math::BigInt operator overloading modifying argument? #7408
Comments
From @pjacklamCreated by @pjacklamAccording to the docs, the a Math::BigFloat object should First, subtracting an element from itself should give 0... $ perl -MMath::BigFloat -wle \ $ perl -MMath::BigFloat -wle \ What was that? Secondly, dividing an element by itself should give 1... $ perl -MMath::BigFloat -wle \ $ perl -MMath::BigFloat -wle \ What was that? This also happens with Math::BigInt objects: $ perl -MMath::BigInt -wle \ $ perl -MMath::BigInt -wle \ The module version numbers are $ perl -MMath::BigFloat -wle 'print Math::BigFloat->VERSION' $ perl -MMath::BigInt -wle 'print Math::BigInt->VERSION' Perl Info
|
From perl_dummy@bloodgate.com-----BEGIN PGP SIGNED MESSAGE----- Moin Peter, you wrote:
Thanx for your report! I just checked that the bug still occurs with v1.70 (the latest version) perl -MMath::BigFloat -wle Ugh! Also: te@linux:~> perl -MMath::BigFloat -wle \ E.g. it is not something in the overloading code. I strongly suspect that it I'll investigate this and try to find a fix. Best wishes, Tels - -- "Our second big loss has been the "IP" fudge, which is blurring the -----BEGIN PGP SIGNATURE----- iQEVAwUBQOwphncLPEOTuEwVAQFcRwf+K4oCerpky1Cjo2HLQbveWoNSm+0Ju1Sn |
The RT System itself - Status changed from 'new' to 'open' |
From @pjacklam"Tels via RT" <perlbug-followup@perl.org> wrote:
After I posted my initial question on comp.lang.perl.misc
I see. Well, I'm glad you were able to reproduce it. It caused Peter -- |
From perl_dummy@bloodgate.com-----BEGIN PGP SIGNED MESSAGE----- Moin, On Wednesday 07 July 2004 18:49, Tels wrote:
The culprit is that code part in bsub(): $y->{sign} =~ tr/+\-/-+/; # does nothing for NaN This clever optimization fails if $x and $y point to the same scalar. *sigh* Adding something like (but not exactly because that fails other tests): if (ref($x) == ref($y)) make it pass that test. Note that: perl -MMath::BigInt=:constant -le 'my $x = 3; print $x - $x;' The first test already passed because "$x = $x - $x" makes a copy of one of I have not yet investigated the bdiv() bug thouroughly, but I think the E.g: * $x / $x => result is one (same ref to $x) However, I have a problem finding out whether two scalars are the same. In if ($x == $y) however, in case of blessed references this doesn't work (overloadig steps Best wishes, Tels - -- Marketing lesson #1: The synergy of the result driven leverage can *never* -----BEGIN PGP SIGNATURE----- iQEVAwUBQOw1nncLPEOTuEwVAQE4+gf/TOkJukdqIt9pnakkRic21g6Ae7Sr6g+e |
From @ysthOn Wed, Jul 07, 2004 at 07:40:38PM +0200, Tels <perl_dummy@bloodgate.com> wrote:
Scalar::Util::refaddr (a fairly recent addition) |
From perl_dummy@bloodgate.com-----BEGIN PGP SIGNED MESSAGE----- Moin, On Thursday 08 July 2004 00:04, Yitzchak Scott-Thoennes wrote:
Means: * loading another module (memory, loading time, etc) Is there no pure-perl solution? I guess not :-( Somehow I resent to use Scalar::Util just to fix the single case of "$x -= Best wishes, Tels - -- 'Wie Ludger L�genboldt, Sprecher der Interessengemeinschaft F�rderer der -----BEGIN PGP SIGNATURE----- iQEVAwUBQOx1I3cLPEOTuEwVAQElXgf9GI4qu5qhShKDT3kbt2WZnE9EST5FG6F2 |
From @pjacklam"Tels via RT" <perlbug-followup@perl.org> wrote:
You might be looking for "overload::StrVal()", as suggested in the $ perl -MMath::BigInt=:constant -wle \ So if (overload::StrVal($x) == overload::StrVal($y)) Kind regards, Peter -- |
From @pjacklam"Yitzchak Scott-Thoennes via RT" <perlbug-followup@perl.org> wrote:
I suggested overload::StrVal() Does it not suite your needs or did my previous message not get Peter -- |
From @ysthOn Thu, Jul 08, 2004 at 12:23:11AM +0200, "Peter J. Acklam" <pjacklam@online.no> wrote:
It eventually got through :) |
From perl_dummy@bloodgate.com-----BEGIN PGP SIGNED MESSAGE----- Moin, Peter, I am sorry that this bug has bitten you. More below: "Yitzchak Scott-Thoennes via RT" <perlbug-followup@perl.org> wrote:
I only saw most of the replies on the p5p webarchive, not per email. Please
Since Math::BigInt does do "use overload ..." I think StrVal should always One small problem: BigInt should also run on older Perls (and I would like Best wishes, Tels PS: I am rather busy this weekend, but I try to bring out a new version - -- "Some spammers have this warped idea that their freedom of speech is -----BEGIN PGP SIGNATURE----- iQEVAwUBQO2sxHcLPEOTuEwVAQGPUgf7BETqMyywSS6ounAfGcuG23QyvPM6OpXf |
From perl_dummy@bloodgate.com-----BEGIN PGP SIGNED MESSAGE----- Moin, I have uploaded a preview of v1.71 on: http://bloodgate.com/perl/packages/devel/Math-BigInt-1.71.tar.gz It seems to fix both bugs, but more work remains on: * adding more tests (other ops, cornercases) If you find anything else, please drop me a note. Cheers, Tels - -- "Schau, schau, Schoschonen." -----BEGIN PGP SIGNATURE----- iQEVAwUBQO2v+HcLPEOTuEwVAQFlrQf9FbgdVPp6Fsk+cvz/dnDlAMS3aASodb8G |
From @ysthOn Thu, Jul 08, 2004 at 10:21:24PM +0200, Tels <perl_dummy@bloodgate.com> wrote:
Yes.
overload is in 5.003_07 (the oldest version still on CPAN) and has |
From perl_dummy@bloodgate.com-----BEGIN PGP SIGNED MESSAGE----- Moin, On Thursday 08 July 2004 22:54, Yitzchak Scott-Thoennes wrote:
Thanx, that fixes these issues for me and I learned something. Thanx again Tels - -- "Not King yet." -----BEGIN PGP SIGNATURE----- iQEVAwUBQO23fXcLPEOTuEwVAQFqEQf8CCudcXaW5TowN52CFSQBepq1C4SxWbS1 |
From @pjacklamTels <perl_dummy@bloodgate.com> wrote:
Morn, [That wasn't a typo. It's Norwegian. :-)]
It builds, passes all tests, and seems to work perfectly on my Peter -- |
From perl_dummy@bloodgate.com-----BEGIN PGP SIGNED MESSAGE----- Moin, I put up a first try on Math::BigInt v1.71 at http://bloodgate.com/perl/packages/devel/Math::BigInt-1.71.tar.gz A patch against bleadperl is attached. Please integrate, so that the smokers Things changed/fixed: * bug in $x -= $x in MBI and MBF Both bugs were found by Peter J. Acklam - thanx! The fix for both bugs only * bsub() in MBF needless overwrote MBI's version The bug 30609 could also be closed. Best wishes, Tels - -- "Schau, schau, Schoschonen." -----BEGIN PGP SIGNATURE----- iQEVAwUBQPk2QXcLPEOTuEwVAQF79wf9Ex83dUH5F/phkaZqnwsdiePacSdtiiUX |
From perl_dummy@bloodgate.comInline Patchdiff -ruN blead/lib/Math/BigFloat.pm blead.patch/lib/Math/BigFloat.pm
--- blead/lib/Math/BigFloat.pm 2004-03-12 21:31:58.000000000 +0100
+++ blead.patch/lib/Math/BigFloat.pm 2004-07-17 15:14:54.000000000 +0200
@@ -12,14 +12,14 @@
# _a : accuracy
# _p : precision
-$VERSION = '1.44';
+$VERSION = '1.45';
require 5.005;
require Exporter;
@ISA = qw(Exporter Math::BigInt);
use strict;
-# $_trap_inf and $_trap_nan are internal and should never be accessed from the outside
+# $_trap_inf/$_trap_nan are internal and should never be accessed from outside
use vars qw/$AUTOLOAD $accuracy $precision $div_scale $round_mode $rnd_mode
$upgrade $downgrade $_trap_nan $_trap_inf/;
my $class = "Math::BigFloat";
@@ -626,30 +626,7 @@
$x->bnorm()->round($a,$p,$r,$y);
}
-sub bsub
- {
- # (BigFloat or num_str, BigFloat or num_str) return BigFloat
- # subtract second arg from first, modify first
-
- # set up parameters
- my ($self,$x,$y,$a,$p,$r) = (ref($_[0]),@_);
- # objectify is costly, so avoid it
- if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
- {
- ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
- }
-
- if ($y->is_zero()) # still round for not adding zero
- {
- return $x->round($a,$p,$r);
- }
-
- # $x - $y = -$x + $y
- $y->{sign} =~ tr/+-/-+/; # does nothing for NaN
- $x->badd($y,$a,$p,$r); # badd does not leave internal zeros
- $y->{sign} =~ tr/+-/-+/; # refix $y (does nothing for NaN)
- $x; # already rounded by badd()
- }
+# sub bsub is inherited from Math::BigInt!
sub binc
{
@@ -1293,39 +1270,52 @@
# enough...
$scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
}
+
+ my $rem; $rem = $self->bzero() if wantarray;
+
+ $y = $self->new($y) unless $y->isa('Math::BigFloat');
+
my $lx = $MBI->_len($x->{_m}); my $ly = $MBI->_len($y->{_m});
$scale = $lx if $lx > $scale;
$scale = $ly if $ly > $scale;
my $diff = $ly - $lx;
$scale += $diff if $diff > 0; # if lx << ly, but not if ly << lx!
-
- # make copy of $x in case of list context for later reminder calculation
- my $rem;
- if (wantarray && !$y->is_one())
+
+ # cases like $x /= $x (but not $x /= $y!) were wrong due to modifying $x
+ # twice below)
+ if (overload::StrVal($x) eq overload::StrVal($y))
{
- $rem = $x->copy();
+ $x->bone(); # x/x => 1, rem 0
}
-
- $x->{sign} = $x->{sign} ne $y->sign() ? '-' : '+';
-
- # check for / +-1 ( +/- 1E0)
- if (!$y->is_one())
+ else
{
- # promote BigInts and it's subclasses (except when already a BigFloat)
- $y = $self->new($y) unless $y->isa('Math::BigFloat');
+
+ # make copy of $x in case of list context for later reminder calculation
+ if (wantarray && !$y->is_one())
+ {
+ $rem = $x->copy();
+ }
- # calculate the result to $scale digits and then round it
- # a * 10 ** b / c * 10 ** d => a/c * 10 ** (b-d)
- $MBI->_lsft($x->{_m},$MBI->_new($scale),10);
- $MBI->_div ($x->{_m},$y->{_m} ); # a/c
+ $x->{sign} = $x->{sign} ne $y->sign() ? '-' : '+';
- ($x->{_e},$x->{_es}) =
- _e_sub($x->{_e}, $y->{_e}, $x->{_es}, $y->{_es});
- # correct for 10**scale
- ($x->{_e},$x->{_es}) =
- _e_sub($x->{_e}, $MBI->_new($scale), $x->{_es}, '+');
- $x->bnorm(); # remove trailing 0's
- }
+ # check for / +-1 ( +/- 1E0)
+ if (!$y->is_one())
+ {
+ # promote BigInts and it's subclasses (except when already a BigFloat)
+ $y = $self->new($y) unless $y->isa('Math::BigFloat');
+
+ # calculate the result to $scale digits and then round it
+ # a * 10 ** b / c * 10 ** d => a/c * 10 ** (b-d)
+ $MBI->_lsft($x->{_m},$MBI->_new($scale),10);
+ $MBI->_div ($x->{_m},$y->{_m}); # a/c
+
+ # correct exponent of $x
+ ($x->{_e},$x->{_es}) = _e_sub($x->{_e}, $y->{_e}, $x->{_es}, $y->{_es});
+ # correct for 10**scale
+ ($x->{_e},$x->{_es}) = _e_sub($x->{_e}, $MBI->_new($scale), $x->{_es}, '+');
+ $x->bnorm(); # remove trailing 0's
+ }
+ } # ende else $x != $y
# shortcut to not run through _find_round_parameters again
if (defined $params[0])
@@ -1343,17 +1333,13 @@
# clear a/p after round, since user did not request it
delete $x->{_a}; delete $x->{_p};
}
-
+
if (wantarray)
{
if (!$y->is_one())
{
$rem->bmod($y,@params); # copy already done
}
- else
- {
- $rem = $self->bzero();
- }
if ($fallback)
{
# clear a/p after round, since user did not request it
diff -ruN blead/lib/Math/BigInt/Calc.pm blead.patch/lib/Math/BigInt/Calc.pm
--- blead/lib/Math/BigInt/Calc.pm 2004-02-19 22:39:28.000000000 +0100
+++ blead.patch/lib/Math/BigInt/Calc.pm 2004-07-17 16:18:59.000000000 +0200
@@ -6,7 +6,7 @@
use vars qw/$VERSION/;
-$VERSION = '0.40';
+$VERSION = '0.41';
# Package to store unsigned big integers in decimal and do math with them
@@ -97,6 +97,21 @@
return ($BASE_LEN, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN_SMALL, $MAX_VAL);
}
+sub _new
+ {
+ # (ref to string) return ref to num_array
+ # Convert a number from string format (without sign) to internal base
+ # 1ex format. Assumes normalized value as input.
+ my $il = length($_[1])-1;
+
+ # < BASE_LEN due len-1 above
+ return [ int($_[1]) ] if $il < $BASE_LEN; # shortcut for short numbers
+
+ # this leaves '00000' instead of int 0 and will be corrected after any op
+ [ reverse(unpack("a" . ($il % $BASE_LEN+1)
+ . ("a$BASE_LEN" x ($il / $BASE_LEN)), $_[1])) ];
+ }
+
BEGIN
{
# from Daniel Pfeiffer: determine largest group of digits that is precisely
@@ -123,28 +138,7 @@
use integer;
- ############################################################################
- # the next block is no longer important
-
- ## this below detects 15 on a 64 bit system, because after that it becomes
- ## 1e16 and not 1000000 :/ I can make it detect 18, but then I get a lot of
- ## test failures. Ugh! (Tomake detect 18: uncomment lines marked with *)
-
- #my $bi = 5; # approx. 16 bit
- #$num = int('9' x $bi);
- ## $num = 99999; # *
- ## while ( ($num+$num+1) eq '1' . '9' x $bi) # *
- #while ( int($num+$num+1) eq '1' . '9' x $bi)
- # {
- # $bi++; $num = int('9' x $bi);
- # # $bi++; $num *= 10; $num += 9; # *
- # }
- #$bi--; # back off one step
- # by setting them equal, we ignore the findings and use the default
- # one-size-fits-all approach from former versions
- my $bi = $e; # XXX, this should work always
-
- __PACKAGE__->_base_len($e,$bi); # set and store
+ __PACKAGE__->_base_len($e); # set and store
# 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.
@@ -179,32 +173,13 @@
} while ($OR_BITS < $max && $x == $z && $y == $x);
$OR_BITS --; # retreat one step
- }
-
-###############################################################################
-
-sub _new
- {
- # (ref to string) return ref to num_array
- # Convert a number from string format (without sign) to internal base
- # 1ex format. Assumes normalized value as input.
- my $il = length($_[1])-1;
-
- # < BASE_LEN due len-1 above
- return [ int($_[1]) ] if $il < $BASE_LEN; # shortcut for short numbers
-
- # this leaves '00000' instead of int 0 and will be corrected after any op
- [ reverse(unpack("a" . ($il % $BASE_LEN+1)
- . ("a$BASE_LEN" x ($il / $BASE_LEN)), $_[1])) ];
- }
-
-BEGIN
- {
$AND_MASK = __PACKAGE__->_new( ( 2 ** $AND_BITS ));
$XOR_MASK = __PACKAGE__->_new( ( 2 ** $XOR_BITS ));
$OR_MASK = __PACKAGE__->_new( ( 2 ** $OR_BITS ));
}
+###############################################################################
+
sub _zero
{
# create a zero
@@ -968,7 +943,7 @@
my $elem = int($n / $BASE_LEN); # which array element
my $digit = $n % $BASE_LEN; # which digit in this element
- $elem = '0000'.@$x[$elem]; # get element padded with 0's
+ $elem = '0000000'.@$x[$elem]; # get element padded with 0's
substr($elem,-$digit-1,1);
}
@@ -1761,11 +1736,7 @@
my ($c,$x) = @_;
# fit's into one element (handle also 0x0 case)
- if (@$x == 1)
- {
- my $t = sprintf("0x%x",$x->[0]);
- return $t;
- }
+ return sprintf("0x%x",$x->[0]) if @$x == 1;
my $x1 = _copy($c,$x);
@@ -1779,7 +1750,6 @@
{
$x10000 = [ 0x1000 ]; $h = 'h3';
}
- # while (! _is_zero($c,$x1))
while (@$x1 != 1 || $x1->[0] != 0) # _is_zero()
{
($x1, $xr) = _div($c,$x1,$x10000);
@@ -1787,8 +1757,7 @@
}
$es = reverse $es;
$es =~ s/^[0]+//; # strip leading zeros
- $es = '0x' . $es;
- $es;
+ '0x' . $es; # return result prepended with 0x
}
sub _as_bin
@@ -1819,7 +1788,6 @@
{
$x10000 = [ 0x1000 ]; $b = 'b12';
}
- # while (! _is_zero($c,$x1))
while (!(@$x1 == 1 && $x1->[0] == 0)) # _is_zero()
{
($x1, $xr) = _div($c,$x1,$x10000);
@@ -1828,8 +1796,7 @@
}
$es = reverse $es;
$es =~ s/^[0]+//; # strip leading zeros
- $es = '0b' . $es;
- $es;
+ '0b' . $es; # return result prepended with 0b
}
sub _from_hex
@@ -1837,19 +1804,26 @@
# convert a hex number to decimal (ref to string, return ref to array)
my ($c,$hs) = @_;
+ my $m = [ 0x10000000 ]; # 28 bit at a time (<32 bit!)
+ my $d = 7; # 7 digits at a time
+ if ($] <= 5.006)
+ {
+ # for older Perls, play safe
+ $m = [ 0x10000 ]; # 16 bit at a time (<32 bit!)
+ $d = 4; # 4 digits at a time
+ }
+
my $mul = _one();
- my $m = [ 0x10000 ]; # 16 bit at a time
my $x = _zero();
- my $len = length($hs)-2;
- $len = int($len/4); # 4-digit parts, w/o '0x'
- my $val; my $i = -4;
+ my $len = int( (length($hs)-2)/$d ); # $d digit parts, w/o the '0x'
+ my $val; my $i = -$d;
while ($len >= 0)
{
- $val = substr($hs,$i,4);
+ $val = substr($hs,$i,$d); # get hex digits
$val =~ s/^[+-]?0x// if $len == 0; # for last part only because
$val = hex($val); # hex does not like wrong chars
- $i -= 4; $len --;
+ $i -= $d; $len --;
_add ($c, $x, _mul ($c, [ $val ], $mul ) ) if $val != 0;
_mul ($c, $mul, $m ) if $len >= 0; # skip last mul
}
@@ -1868,9 +1842,9 @@
$hs =~ s/^[+-]?0b//; # remove sign and 0b
my $l = length($hs); # bits
$hs = '0' x (8-($l % 8)) . $hs if ($l % 8) != 0; # padd left side w/ 0
- my $h = unpack('H*', pack ('B*', $hs)); # repack as hex
+ my $h = '0x' . unpack('H*', pack ('B*', $hs)); # repack as hex
- $c->_from_hex('0x'.$h);
+ $c->_from_hex($h);
}
##############################################################################
@@ -1903,8 +1877,7 @@
# if the gcd is not 1, then return NaN
return (undef,undef) unless _is_one($c,$a);
- $sign = $sign == 1 ? '+' : '-';
- ($u1,$sign);
+ ($u1, $sign == 1 ? '+' : '-');
}
sub _modpow
diff -ruN blead/lib/Math/BigInt/t/bare_mbf.t blead.patch/lib/Math/BigInt/t/bare_mbf.t
--- blead/lib/Math/BigInt/t/bare_mbf.t 2004-03-12 21:31:58.000000000 +0100
+++ blead.patch/lib/Math/BigInt/t/bare_mbf.t 2004-07-17 16:06:04.000000000 +0200
@@ -27,7 +27,7 @@
}
print "# INC = @INC\n";
- plan tests => 1815;
+ plan tests => 1835;
}
use Math::BigFloat lib => 'BareCalc';
diff -ruN blead/lib/Math/BigInt/t/bare_mbi.t blead.patch/lib/Math/BigInt/t/bare_mbi.t
--- blead/lib/Math/BigInt/t/bare_mbi.t 2004-02-19 22:39:28.000000000 +0100
+++ blead.patch/lib/Math/BigInt/t/bare_mbi.t 2004-07-17 16:05:29.000000000 +0200
@@ -26,7 +26,7 @@
}
print "# INC = @INC\n";
- plan tests => 2832;
+ plan tests => 2848;
}
use Math::BigInt lib => 'BareCalc';
diff -ruN blead/lib/Math/BigInt/t/bigfltpm.inc blead.patch/lib/Math/BigInt/t/bigfltpm.inc
--- blead/lib/Math/BigInt/t/bigfltpm.inc 2004-03-12 21:31:58.000000000 +0100
+++ blead.patch/lib/Math/BigInt/t/bigfltpm.inc 2004-07-17 16:04:54.000000000 +0200
@@ -257,6 +257,34 @@
ok ($class->new(1)->fdiv('0.5')->bsstr(),'2e+0');
+###############################################################################
+# [perl #30609] bug with $x -= $x not beeing 0, but 2*$x
+
+$x = $class->new(3); $x -= $x; ok ($x, 0);
+$x = $class->new(-3); $x -= $x; ok ($x, 0);
+$x = $class->new(3); $x += $x; ok ($x, 6);
+$x = $class->new(-3); $x += $x; ok ($x, -6);
+
+$x = $class->new('NaN'); $x -= $x; ok ($x->is_nan(), 1);
+$x = $class->new('inf'); $x -= $x; ok ($x->is_nan(), 1);
+$x = $class->new('-inf'); $x -= $x; ok ($x->is_nan(), 1);
+
+$x = $class->new('NaN'); $x += $x; ok ($x->is_nan(), 1);
+$x = $class->new('inf'); $x += $x; ok ($x->is_inf(), 1);
+$x = $class->new('-inf'); $x += $x; ok ($x->is_inf('-'), 1);
+
+$x = $class->new('3.14'); $x -= $x; ok ($x, 0);
+$x = $class->new('-3.14'); $x -= $x; ok ($x, 0);
+$x = $class->new('3.14'); $x += $x; ok ($x, '6.28');
+$x = $class->new('-3.14'); $x += $x; ok ($x, '-6.28');
+
+$x = $class->new('3.14'); $x *= $x; ok ($x, '9.8596');
+$x = $class->new('-3.14'); $x *= $x; ok ($x, '9.8596');
+$x = $class->new('3.14'); $x /= $x; ok ($x, '1');
+$x = $class->new('-3.14'); $x /= $x; ok ($x, '1');
+$x = $class->new('3.14'); $x %= $x; ok ($x, '0');
+$x = $class->new('-3.14'); $x %= $x; ok ($x, '0');
+
1; # all done
###############################################################################
diff -ruN blead/lib/Math/BigInt/t/bigfltpm.t blead.patch/lib/Math/BigInt/t/bigfltpm.t
--- blead/lib/Math/BigInt/t/bigfltpm.t 2004-03-12 21:31:58.000000000 +0100
+++ blead.patch/lib/Math/BigInt/t/bigfltpm.t 2004-07-17 16:05:51.000000000 +0200
@@ -26,7 +26,7 @@
}
print "# INC = @INC\n";
- plan tests => 1815
+ plan tests => 1835
+ 2; # own tests
}
diff -ruN blead/lib/Math/BigInt/t/bigintpm.inc blead.patch/lib/Math/BigInt/t/bigintpm.inc
--- blead/lib/Math/BigInt/t/bigintpm.inc 2004-02-19 22:39:28.000000000 +0100
+++ blead.patch/lib/Math/BigInt/t/bigintpm.inc 2004-07-17 16:04:33.000000000 +0200
@@ -624,6 +624,28 @@
ok ($class->new(-1)->is_one(),0);
###############################################################################
+# [perl #30609] bug with $x -= $x not beeing 0, but 2*$x
+
+$x = $class->new(3); $x -= $x; ok ($x, 0);
+$x = $class->new(-3); $x -= $x; ok ($x, 0);
+$x = $class->new('NaN'); $x -= $x; ok ($x->is_nan(), 1);
+$x = $class->new('inf'); $x -= $x; ok ($x->is_nan(), 1);
+$x = $class->new('-inf'); $x -= $x; ok ($x->is_nan(), 1);
+
+$x = $class->new('NaN'); $x += $x; ok ($x->is_nan(), 1);
+$x = $class->new('inf'); $x += $x; ok ($x->is_inf(), 1);
+$x = $class->new('-inf'); $x += $x; ok ($x->is_inf('-'), 1);
+$x = $class->new(3); $x += $x; ok ($x, 6);
+$x = $class->new(-3); $x += $x; ok ($x, -6);
+
+$x = $class->new(3); $x *= $x; ok ($x, 9);
+$x = $class->new(-3); $x *= $x; ok ($x, 9);
+$x = $class->new(3); $x /= $x; ok ($x, 1);
+$x = $class->new(-3); $x /= $x; ok ($x, 1);
+$x = $class->new(3); $x %= $x; ok ($x, 0);
+$x = $class->new(-3); $x %= $x; ok ($x, 0);
+
+###############################################################################
# all tests done
1;
diff -ruN blead/lib/Math/BigInt/t/bigintpm.t blead.patch/lib/Math/BigInt/t/bigintpm.t
--- blead/lib/Math/BigInt/t/bigintpm.t 2004-02-19 22:39:28.000000000 +0100
+++ blead.patch/lib/Math/BigInt/t/bigintpm.t 2004-07-17 16:05:14.000000000 +0200
@@ -10,7 +10,7 @@
my $location = $0; $location =~ s/bigintpm.t//;
unshift @INC, $location; # to locate the testing files
chdir 't' if -d 't';
- plan tests => 2832;
+ plan tests => 2848;
}
use Math::BigInt;
diff -ruN blead/lib/Math/BigInt/t/sub_mbf.t blead.patch/lib/Math/BigInt/t/sub_mbf.t
--- blead/lib/Math/BigInt/t/sub_mbf.t 2004-03-12 21:31:58.000000000 +0100
+++ blead.patch/lib/Math/BigInt/t/sub_mbf.t 2004-07-17 16:06:13.000000000 +0200
@@ -26,7 +26,7 @@
}
print "# INC = @INC\n";
- plan tests => 1815
+ plan tests => 1835
+ 6; # + our own tests
}
diff -ruN blead/lib/Math/BigInt/t/sub_mbi.t blead.patch/lib/Math/BigInt/t/sub_mbi.t
--- blead/lib/Math/BigInt/t/sub_mbi.t 2004-02-19 22:39:28.000000000 +0100
+++ blead.patch/lib/Math/BigInt/t/sub_mbi.t 2004-07-17 16:05:36.000000000 +0200
@@ -26,7 +26,7 @@
}
print "# INC = @INC\n";
- plan tests => 2832
+ plan tests => 2848
+ 5; # +5 own tests
}
diff -ruN blead/lib/Math/BigInt/t/with_sub.t blead.patch/lib/Math/BigInt/t/with_sub.t
--- blead/lib/Math/BigInt/t/with_sub.t 2004-03-12 21:31:58.000000000 +0100
+++ blead.patch/lib/Math/BigInt/t/with_sub.t 2004-07-17 16:06:25.000000000 +0200
@@ -28,7 +28,7 @@
}
print "# INC = @INC\n";
- plan tests => 1815
+ plan tests => 1835
+ 1;
}
diff -ruN blead/lib/Math/BigInt.pm blead.patch/lib/Math/BigInt.pm
--- blead/lib/Math/BigInt.pm 2004-04-23 23:05:07.000000000 +0200
+++ blead.patch/lib/Math/BigInt.pm 2004-07-08 22:17:28.000000000 +0200
@@ -18,7 +18,7 @@
my $class = "Math::BigInt";
require 5.005;
-$VERSION = '1.70_01';
+$VERSION = '1.71';
use Exporter;
@ISA = qw( Exporter );
@EXPORT_OK = qw( objectify bgcd blcm);
@@ -1140,6 +1140,13 @@
return $x;
}
+ if (overload::StrVal($x) eq overload::StrVal($y))
+ {
+ # if we get the same variable twice, the result must be zero (the code
+ # below fails in that case)
+ return $x->bzero(@r) if $x->{sign} =~ /^[+-]$/;
+ return $x->bnan(); # NaN, -inf, +inf
+ }
$y->{sign} =~ tr/+\-/-+/; # does nothing for NaN
$x->badd($y,@r); # badd does not leave internal zeros
$y->{sign} =~ tr/+\-/-+/; # refix $y (does nothing for NaN) |
From @rgsTels wrote:
Thanks, applied as #23142. |
@rgs - Status changed from 'open' to 'resolved' |
Migrated from rt.perl.org#30609 (status was 'resolved')
Searchable as RT30609$
The text was updated successfully, but these errors were encountered: