Skip to content
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

Closed
p5pRT opened this issue Jul 6, 2004 · 19 comments
Closed

Comments

@p5pRT
Copy link

p5pRT commented Jul 6, 2004

Migrated from rt.perl.org#30609 (status was 'resolved')

Searchable as RT30609$

@p5pRT
Copy link
Author

p5pRT commented Jul 6, 2004

From @pjacklam

Created by @pjacklam

According to the docs, the a Math​::BigFloat object should
not be modified when overloaded operators are used. However,
with the operators "-=", "/=" etc. the argument should be
modified, and it is, but incorrectly.

First, subtracting an element from itself should give 0...

  $ perl -MMath​::BigFloat -wle \
  '$x = Math​::BigFloat->new(3.14) ; $x = $x - $x ; print $x'
  0

  $ perl -MMath​::BigFloat -wle \
  '$x = Math​::BigFloat->new(3.14) ; $x -= $x ; print $x'
  6.28
  ^^^^

What was that?

Secondly, dividing an element by itself should give 1...

  $ perl -MMath​::BigFloat -wle \
  '$x = Math​::BigFloat->new(3.14) ; $x = $x / $x ; print $x'
  1 # OK; x / x = 1

  $ perl -MMath​::BigFloat -wle \
  '$x = Math​::BigFloat->new(3.14) ; $x /= $x ; print $x'
  0.00000000000000000000000000000000000000000001
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

What was that?

This also happens with Math​::BigInt objects​:

  $ perl -MMath​::BigInt -wle \
  '$x = Math​::BigInt->new(314) ; $x = $x - $x ; print $x'
  0

  $ perl -MMath​::BigInt -wle \
  '$x = Math​::BigInt->new(314) ; $x -= $x ; print $x'
  628

The module version numbers are

  $ perl -MMath​::BigFloat -wle 'print Math​::BigFloat->VERSION'
  1.40

  $ perl -MMath​::BigInt -wle 'print Math​::BigInt->VERSION'
  1.66

Perl Info

Flags:
    category=library
    severity=medium

Site configuration information for perl v5.8.2:

Configured by Gerrit at Fri Nov  7 12:03:56     2003.

Summary of my perl5 (revision 5.0 version 8 subversion 2) configuration:
  Platform:
    osname=cygwin, osvers=1.5.5(0.9432), archname=cygwin-thread-multi-64int
    uname='cygwin_nt-5.0 troubardix 1.5.5(0.9432) 2003-09-20 16:31 i686 unknown unknown cygwin '
    config_args='-de -Dmksymlinks -Duse64bitint -Dusethreads -Doptimize=-O2 -Dman3ext=3pm'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=define use64bitall=undef uselongdouble=undef
    usemymalloc=y, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-DPERL_USE_SAFE_PUTENV -fno-strict-aliasing',
    optimize='-O2',
    cppflags='-DPERL_USE_SAFE_PUTENV -fno-strict-aliasing'
    ccversion='', gccversion='3.3.1 (cygming special)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='ld2', ldflags =' -s -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib /lib
    libs=-lgdbm -ldb -lcrypt -lgdbm_compat
    perllibs=-lcrypt -lgdbm_compat
    libc=/usr/lib/libc.a, so=dll, useshrplib=true, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' -s'
    cccdlflags=' ', lddlflags=' -s -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.8.2:
    /usr/lib/perl5/5.8.2/cygwin-thread-multi-64int
    /usr/lib/perl5/5.8.2
    /usr/lib/perl5/site_perl/5.8.2/cygwin-thread-multi-64int
    /usr/lib/perl5/site_perl/5.8.2
    /usr/lib/perl5/site_perl
    .


Environment for perl v5.8.2:
    HOME=/cygdrive/h/home/peter
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/local/bin:/usr/bin:/cygdrive/c/WINNT/system32:/cygdrive/c/WINNT:/cygdrive/c/WINNT/System32/Wbem:/cygdrive/c/apps/matlab6p5p1/bin/win32:/usr/local/bin:/usr/bin:/cygdrive/c/WINNT/system32:/cygdrive/c/WINNT:/cygdrive/c/WINNT/System32/Wbem:/cygdrive/c/apps/matlab6p5p1/bin/win32:/cygdrive/h/home/peter/bin/os/wincmd/scripts:/usr/lib/perl5/cpan/bin:/cygdrive/i/perl/cpan/bin:/cygdrive/h/home/peter/bin/os/unix/scripts:/cygdrive/h/home/peter/bin/os/unix/links:/cygdrive/c/Programfiler/GnuWin32/bin
    PERL_BADLANG (unset)
    SHELL (unset)




@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin Peter,

you wrote​:

According to the docs, the a Math​::BigFloat object should
not be modified when overloaded operators are used. However,
with the operators "-=", "/=" etc. the argument should be
modified, and it is, but incorrectly.

First, subtracting an element from itself should give 0...
[snip]

Thanx for your report!

I just checked that the bug still occurs with v1.70 (the latest version)
using a Perl v5.8.3​:

  perl -MMath​::BigFloat -wle
  '$x = Math​::BigFloat->new(3.14) ; $x -= $x ; print $x'
  6.28

Ugh! Also​:

  te@​linux​:~> perl -MMath​::BigFloat -wle \
  '$x = Math​::BigFloat->new(3.14) ; $x->bsub($x) ; print $x'
  6.28
  te@​linux​:~> perl -MMath​::BigFloat -wle \
  '$x = Math​::BigFloat->new(3.14) ; $x = $x->bsub($x) ; print $x'
  6.28

E.g. it is not something in the overloading code. I strongly suspect that it
is the issue with bdiv()/bsub() etc not recognising that you pass it the
same variable twice. The "bug" would thus appear to be in Calc.pm.

I'll investigate this and try to find a fix.

Best wishes,

Tels

- --
Signed on Wed Jul 7 18​:48​:42 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

"Our second big loss has been the "IP" fudge, which is blurring the
distinctions between patents, copyrights, trademarks, trade secrets,
competative advantages, wishful thinking, bullshit, and marketing babble
into one vague pile of lawyer poo." -- MarkusQ (450076), 2004-01-23

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQOwphncLPEOTuEwVAQFcRwf+K4oCerpky1Cjo2HLQbveWoNSm+0Ju1Sn
gdzvWmpJAtpak+UGdfTWlcnf9DKLxFIgeuswlWbfrFsZhZwrfjLkvpnrDywMM3ic
PQKyhzIl1YeyJm6plYtNM8myYNKiYQkF8aPhSYJVC7Q5hvGUgMLLj9FmLlSqXbp6
bZfTlJ/S69k0+z9MvGYwGXsKUrFAI/oK71Ku7kQSxAvwkgsgkf7hxxfON4Y3K8sT
AbBaieOURaVxnBt65eMSUgSGmijqOhejMXju0vH0J5UxSOgHQ3L+97Orn7K83dwl
CdsfBbAWQZANa3aKzRbiVo7f0ig9y8dr/cz+/A+L0FUuNNGAsSMV9w==
=2Gg4
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2004

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2004

From @pjacklam

"Tels via RT" <perlbug-followup@​perl.org> wrote​:

[...]
I strongly suspect that it is the issue with bdiv()/bsub() etc
not recognising that you pass it the same variable twice.

After I posted my initial question on comp.lang.perl.misc
J. Romano <jl_post@​hotmail.com> wrote two postings to that group
where he came to the same "conclusion". He also came up with some
suggestions for a fix. You can have a look at them if you're
interested.

The "bug" would thus appear to be in Calc.pm.

I see. Well, I'm glad you were able to reproduce it. It caused
me a lot of confusion since the actual case wasn't as trivial as
dividing a number by itself directly, but rather via references to
references to...

Peter

--
Peter J. Acklam - pjacklam@​online.no - http​://home.online.no/~pjacklam

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

On Wednesday 07 July 2004 18​:49, Tels wrote​:

Moin Peter,

you wrote​:

According to the docs, the a Math​::BigFloat object should
not be modified when overloaded operators are used. However,
with the operators "-=", "/=" etc. the argument should be
modified, and it is, but incorrectly.

First, subtracting an element from itself should give 0...

[snip]

Thanx for your report!

I just checked that the bug still occurs with v1.70 (the latest version)
using a Perl v5.8.3​:
[snip]
E.g. it is not something in the overloading code. I strongly suspect that
it is the issue with bdiv()/bsub() etc not recognising that you pass it
the same variable twice. The "bug" would thus appear to be in Calc.pm.

The culprit is that code part in bsub()​:

  $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)
  $x; # already rounded by badd() or not necc.
  }

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))
  {
  # if we get the same variable twice, the result must be zero (the code
  # below fails in that case)
  return $x->bzero(@​r);
  }

make it pass that test. Note that​:

  perl -MMath​::BigInt=​:constant -le 'my $x = 3; print $x - $x;'
  0
  perl -MMath​::BigInt=​:constant -le 'my $x = 3; print $x -= $x;'
  6

The first test already passed because "$x = $x - $x" makes a copy of one of
the "$x", then subtracts the "other" $x from it and sets that as the result
of the expression, so bsub() saw two different scalars.

I have not yet investigated the bdiv() bug thouroughly, but I think the
problem is that it actually attempts the division instead of just returning
1. While this requires a (at most O(N)) comparisation it will avoid quite
some fiddling in the case when $x == $y - because attempting to divide the
two numbers get's quite tricky.

E.g​:

* $x / $x => result is one (same ref to $x)
* $y = $x; $x / $y => compare $x to $y (O(N) cost) and save divide
* $x / $y => compare (O(1) .. O(N) depending on $x and $y) and divide

However, I have a problem finding out whether two scalars are the same. In
case of unblessed references I can use​:

  if ($x == $y)
  {
  ...
  ]

however, in case of blessed references this doesn't work (overloadig steps
in :/). Is there a way to find out that two scalars are the same scalar,
e.g. that $x and $y are in fact the same variable?

Best wishes,

Tels

- --
Signed on Wed Jul 7 18​:57​:22 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

Marketing lesson #1​: The synergy of the result driven leverage can *never*
incentivize a paradigm shift. -- Walterk (124748) on 2004-01-16 at /.

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQOw1nncLPEOTuEwVAQE4+gf/TOkJukdqIt9pnakkRic21g6Ae7Sr6g+e
5hpYMkTxQ72YMuK9Aljk/xy7LRvxNp1s2NMxmlww03rfKQG1zDqVXEISE/nb7exd
oBfxYkvmNVyT8MOqX7CiMLhqdBs9163qr1AFnKCevTK/fksKiLfAMHbXzv1p8sQU
DjdQaysMoIY6ngDpkJ9r12qUodLIj1OOr1qiRFuPdcmbRQoHSWpuvL4cNRUEMk/f
9PHGByVbnp0IFrT5spVeYlBqGPUaPQ9X2qF886Lv05OUbMXfzzFEZoxv8eLWjR/p
+023tyPnGeYRz3uz25gtWQuqQLuyfI9Wv/oQNsckCMYGErGiDhyEEQ==
=XopK
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2004

From @ysth

On Wed, Jul 07, 2004 at 07​:40​:38PM +0200, Tels <perl_dummy@​bloodgate.com> wrote​:

however, in case of blessed references this doesn't work (overloadig steps
in :/). Is there a way to find out that two scalars are the same scalar,
e.g. that $x and $y are in fact the same variable?

Scalar​::Util​::refaddr (a fairly recent addition)

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

On Thursday 08 July 2004 00​:04, Yitzchak Scott-Thoennes wrote​:

On Wed, Jul 07, 2004 at 07​:40​:38PM +0200, Tels <perl_dummy@​bloodgate.com>
wrote​:

however, in case of blessed references this doesn't work (overloadig
steps in :/). Is there a way to find out that two scalars are the same
scalar, e.g. that $x and $y are in fact the same variable?

Scalar​::Util​::refaddr (a fairly recent addition)

Means​:

* loading another module (memory, loading time, etc)
* won't work on older Perls without pre-requisites (and maybe not even then)

Is there no pure-perl solution? I guess not :-(

Somehow I resent to use Scalar​::Util just to fix the single case of "$x -=
$x" (for $x /= $x I need to check that $x == $y, anyway, so this means a
full compare is always neccessary).

Best wishes,

Tels

- --
Signed on Thu Jul 8 00​:08​:55 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

'Wie Ludger L�genboldt, Sprecher der Interessengemeinschaft F�rderer der
Prostitution International (I.F.P.I.) jetzt bekannt gab, entstehen der
Zuh�lterbrache j�hrlich Milliardenverluste durch kostenfreien Sex.
"Bestimmt h�tten unsere M�dels im Jahr 2003 alleine in Deutschland 2000
Millionen Quickies mehr verkaufen k�nnen, wenn die Leute nicht immer mehr
privat rumv�geln w�rden. Der uns entstandene Schaden bel�uft sich auf
mindestens 100000000000 Euro." Schuld sei nach Angaben L�genboldts das
Internet​: "Flirtportale und Singlewebsites mit Kontaktb�rsen machen unser
Gesch�ft kaputt. Amateure rauben uns unserer Gesch�ftsgrundlagen."
Zehntausende von Arbeitspl�tzen in Deutschland seien gef�hrdet, die
�berdies gerade geringer qualifizieren jungen Frauen ein Einkommen
sicherten. Die I.F.P.I. fordert den Gesetzgeber auf, diesem Treiben
umgehend Schranken zu setzen.' MI-Boykotteur at 2004-05-07 at
http​://tinyurl.com/35qjo

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQOx1I3cLPEOTuEwVAQElXgf9GI4qu5qhShKDT3kbt2WZnE9EST5FG6F2
slPT7sHVe+/VDFeQGduG72WkkIfAcySS3txPmzifSG9SXHuehBbXB96sEgMa4PCN
F6WcuFu8Fy3Z1l1/r2drm8z0VVGuEO0W5Z6aX+XxUrKogB3H55bTHS46SMXiWyye
Vg6ox3c4jmF9OCiFhuEmYsXqjKOKy/rD+KKb0EzzZxT+ISPpie9zLWeb/z+EKvtt
EHtGW0cDaa9QpKtHGNeV834WyqqG9TjmH2rqHQwsSQptpP8GBwqLaypwpsKez3P1
7tKmFcmToyOfnnIvzrDoanii++UYAR3yErJvTKaFUsmwMXVbCrqgEw==
=2fyf
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2004

From @pjacklam

"Tels via RT" <perlbug-followup@​perl.org> wrote​:

[...] However, I have a problem finding out whether two scalars
are the same. In case of unblessed references I can use​:

if \($x == $y\)
  \{
  \.\.\.
  \]

however, in case of blessed references this doesn't work
(overloadig steps in :/). Is there a way to find out that two
scalars are the same scalar, e.g. that $x and $y are in fact the
same variable?

You might be looking for "overload​::StrVal()", as suggested in the
posting i referred to earlier. :-)

  $ perl -MMath​::BigInt=​:constant -wle \
  'my $x = 3; print overload​::StrVal($x)'
  Math​::BigInt=HASH(0x1012d1a8)

So

  if (overload​::StrVal($x) == overload​::StrVal($y))
  {
  # they are the same
  ...
  }

Kind regards,

Peter

--
Peter J. Acklam - pjacklam@​online.no - http​://home.online.no/~pjacklam

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2004

From @pjacklam

"Yitzchak Scott-Thoennes via RT" <perlbug-followup@​perl.org> wrote​:

On Wed, Jul 07, 2004 at 07​:40​:38PM +0200, Tels <perl_dummy@​bloodgate.com> wrote​:

however, in case of blessed references this doesn't work
(overloadig steps in :/). Is there a way to find out that two
scalars are the same scalar, e.g. that $x and $y are in fact
the same variable?

Scalar​::Util​::refaddr (a fairly recent addition)

I suggested

  overload​::StrVal()

Does it not suite your needs or did my previous message not get
through?

Peter

--
Peter J. Acklam - pjacklam@​online.no - http​://home.online.no/~pjacklam

@p5pRT
Copy link
Author

p5pRT commented Jul 8, 2004

From @ysth

On Thu, Jul 08, 2004 at 12​:23​:11AM +0200, "Peter J. Acklam" <pjacklam@​online.no> wrote​:

"Yitzchak Scott-Thoennes via RT" <perlbug-followup@​perl.org> wrote​:

On Wed, Jul 07, 2004 at 07​:40​:38PM +0200, Tels <perl_dummy@​bloodgate.com> wrote​:

however, in case of blessed references this doesn't work
(overloadig steps in :/). Is there a way to find out that two
scalars are the same scalar, e.g. that $x and $y are in fact
the same variable?

Scalar​::Util​::refaddr (a fairly recent addition)

I suggested

overload&#8203;::StrVal\(\)

Does it not suite your needs or did my previous message not get
through?

It eventually got through :)
That's a much better suggestion. Still requires loading overload.pm,
though. (You can't assume that if overload isn't loaded there are
no overloaded objects, because there's an alternate XS interface now.)

@p5pRT
Copy link
Author

p5pRT commented Jul 8, 2004

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​:

On Thu, Jul 08, 2004 at 12​:23​:11AM +0200, "Peter J. Acklam"
<pjacklam@​online.no> wrote​:

"Yitzchak Scott-Thoennes via RT" <perlbug-followup@​perl.org> wrote​:

On Wed, Jul 07, 2004 at 07​:40​:38PM +0200, Tels
<perl_dummy@​bloodgate.com> wrote​:

however, in case of blessed references this doesn't work
(overloadig steps in :/). Is there a way to find out that two
scalars are the same scalar, e.g. that $x and $y are in fact
the same variable?

Scalar​::Util​::refaddr (a fairly recent addition)

I suggested

overload&#8203;::StrVal\(\)

Does it not suite your needs or did my previous message not get
through?

It eventually got through :)

I only saw most of the replies on the p5p webarchive, not per email. Please
try to keep me in the loop :)

That's a much better suggestion. Still requires loading overload.pm,
though. (You can't assume that if overload isn't loaded there are
no overloaded objects, because there's an alternate XS interface now.)

Since Math​::BigInt does do "use overload ..." I think StrVal should always
available, right?

One small problem​: BigInt should also run on older Perls (and I would like
to fix the bug for them, too). I see overload is not available on
search.cpan.org - how far back would StrVal work? And if not far back
enough (like 5.6.x), would it make sense (be possible?) to put overload.pm
on cpan as a dual-live package?

Best wishes,

Tels

PS​: I am rather busy this weekend, but I try to bring out a new version
early next week fixing both bugs...

- --
Signed on Thu Jul 8 22​:02​:25 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

"Some spammers have this warped idea that their freedom of speech is
guaranteed all the way into my hard drive, but it is my firm belief that
their rights end at my firewall." -- Nigel Featherston

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQO2sxHcLPEOTuEwVAQGPUgf7BETqMyywSS6ounAfGcuG23QyvPM6OpXf
zaFu0So4V63Ritk9qleuVv9BIQUzxVhAndy5rZekUvh47CFrTEa8y1K9bMs7Pv2S
uxZmXpbTAr0IbjPk1AZrbNi6Dd6YwJDls+Rr7F7QmbbD3pNdgWeEV54vOo5Dffrh
vuWu7U980JKSsqHQXCrkVk2EhUWiEQwWMnUVk4ItsYyEscqEKBjgufNGYxBwD/Fm
Hp/xrGY8oplWDANnF6/jVz1UC8+DwXZSnbsxnehOuXBkR3ixWb1soRShGPeotaw3
sJ6Ss68GBMh6OZZk6k79SzbKTq8s/DSX3ZMYDzA4nl5BYw/QHZnRvw==
=/UeR
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Jul 8, 2004

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)
* testing with other modules that depend on BigInt
* testing on older Perls

If you find anything else, please drop me a note.

Cheers,

Tels

- --
Signed on Thu Jul 8 22​:27​:26 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

"Schau, schau, Schoschonen."

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQO2v+HcLPEOTuEwVAQFlrQf9FbgdVPp6Fsk+cvz/dnDlAMS3aASodb8G
k78IFgZpybTOvgpu6mIJWWviaZXh3Kbyh3us/nHzqGCo2TRrpXtfU9JCE812lqpS
YNoTS3GOXVg+rydcIH1p2Hl7Wowmxv7wdGIISIJh5jM5Kja7xa2qa1a/b0Z5x2Oc
PvveHW7OhtFqIeyKc71TFJw79dxCrFNN4RmXxpUgDTdA2WTrB5d4Jn5XiYy/Hrj2
vtRa3NMabnpCVC42KtElVzIrmMLd3YoI2cwJHBBJG9xTaACB9dT/dI83g/NYv4Ap
kmyU2mCftTI1qjnQfqXtOThP4FsJ2NngbmxL+VZi1M6xdXCkZbv7Iw==
=Qfmg
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Jul 8, 2004

From @ysth

On Thu, Jul 08, 2004 at 10​:21​:24PM +0200, Tels <perl_dummy@​bloodgate.com> wrote​:

Since Math​::BigInt does do "use overload ..." I think StrVal should always
available, right?

Yes.

One small problem​: BigInt should also run on older Perls (and I would like
to fix the bug for them, too). I see overload is not available on
search.cpan.org - how far back would StrVal work? And if not far back
enough (like 5.6.x), would it make sense (be possible?) to put overload.pm
on cpan as a dual-live package?

overload is in 5.003_07 (the oldest version still on CPAN) and has
StrVal there.

@p5pRT
Copy link
Author

p5pRT commented Jul 8, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

On Thursday 08 July 2004 22​:54, Yitzchak Scott-Thoennes wrote​:

On Thu, Jul 08, 2004 at 10​:21​:24PM +0200, Tels <perl_dummy@​bloodgate.com>
wrote​:

Since Math​::BigInt does do "use overload ..." I think StrVal should
always available, right?

Yes.

One small problem​: BigInt should also run on older Perls (and I would
like to fix the bug for them, too). I see overload is not available on
search.cpan.org - how far back would StrVal work? And if not far back
enough (like 5.6.x), would it make sense (be possible?) to put
overload.pm on cpan as a dual-live package?

overload is in 5.003_07 (the oldest version still on CPAN) and has
StrVal there.

Thanx, that fixes these issues for me and I learned something. Thanx again
for your time and patience!

Tels

- --
Signed on Thu Jul 8 23​:06​:31 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

"Not King yet."

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQO23fXcLPEOTuEwVAQFqEQf8CCudcXaW5TowN52CFSQBepq1C4SxWbS1
0kCOEIddoYOmdDdcE9Bf1iQWgO8tnZkWEDJkAyRD9N62UKggP4w976dNgPl1Gtyr
1akvMO6akTIOLq3l+yaWp6pDPj5Ywu5t7LK704kFp8GeUgap3YO+veUAlwY6NQlp
HZinMgaGuqmu/nYjoA8yhOQ1jo5u8IwYS2otRVUb3Vth4E1Pq1wCYbukb6nmlItR
GHfrYj+ZesbTPID5p/MDLXPd/BNGgssRVIvC1+R1Pvujkt7vO41HxA32mns9OZj9
eNNnR22MxahfNBMfdx6hQOhAY6hlwBgfdbRdo6l17Xve30BIte5BSg==
=z3nr
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Jul 9, 2004

From @pjacklam

Tels <perl_dummy@​bloodgate.com> wrote​:

Moin,

Morn, [That wasn't a typo. It's Norwegian. :-)]

I have uploaded a preview of v1.71 on​:

http&#8203;://bloodgate\.com/perl/packages/devel/Math\-BigInt\-1\.71\.tar\.gz

It seems to fix both bugs

It builds, passes all tests, and seems to work perfectly on my
system (Cygwin, at the moment).

Peter

--
Peter J. Acklam - pjacklam@​online.no - http​://home.online.no/~pjacklam

@p5pRT
Copy link
Author

p5pRT commented Jul 17, 2004

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
can have a go at it.

Things changed/fixed​:

  * bug in $x -= $x in MBI and MBF
  * bug in $x /= $x in MBF

  Both bugs were found by Peter J. Acklam - thanx! The fix for both bugs only
  involves two calls to overload​::StrVal() and thus hardly has any effect at
  all.

  * bsub() in MBF needless overwrote MBI's version
  * _from_hex() (and thus also _from_bin() because it re-uses it) use now
  more (28 vs 16) bits and are thus faster. A 12000 bit number is now about
  twice as fast converted to a BigInt.

The bug 30609 could also be closed.

Best wishes,

Tels

- --
Signed on Sat Jul 17 16​:14​:09 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

"Schau, schau, Schoschonen."

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQPk2QXcLPEOTuEwVAQF79wf9Ex83dUH5F/phkaZqnwsdiePacSdtiiUX
mUydice/nXKS5xfyxEIz92MjUcN3m+LLiLKbi9/JGbvU9RuCgr1OFTIFZzjKR/K2
4g8F6h67lyMpSiB6BnaiQLmaQeqcNl3IggDVTdZIs3gT3yPECAzWf2C3SVRu+JS5
pwVQfdDCTSnx2hRGF5SZTUYyzEI2FEEa+YamvBDwhM+/KGpcfYr1i7X2l2m6Xs9u
FkZedpIGRuMPt/laA36HMGyR9SW9ZR5pf6op5N4+aE1llwkCJrbR91unfz5toQf3
ZWOxefKlFbF9n0NSSnp4wn91FSyb5V22rz7RohAWAZjGV9CV2MtD+w==
=YpR3
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Jul 17, 2004

From perl_dummy@bloodgate.com

Inline Patch
diff -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)

@p5pRT
Copy link
Author

p5pRT commented Jul 19, 2004

From @rgs

Tels wrote​:

I put up a first try on Math​::BigInt v1.71 at

http&#8203;://bloodgate\.com/perl/packages/devel/Math&#8203;::BigInt\-1\.71\.tar\.gz

A patch against bleadperl is attached. Please integrate, so that the smokers
can have a go at it.

Thanks, applied as #23142.

@p5pRT p5pRT closed this as completed Jul 21, 2004
@p5pRT
Copy link
Author

p5pRT commented Jul 21, 2004

@rgs - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant