Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.9k stars 539 forks source link

Math::BigFloat and Math::BigInt operator overloading modifying argument? #7408

Closed p5pRT closed 20 years ago

p5pRT commented 20 years ago

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

Searchable as RT30609$

p5pRT commented 20 years ago

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 commented 20 years ago

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 commented 20 years ago

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

p5pRT commented 20 years ago

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 commented 20 years ago

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 commented 20 years ago

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 commented 20 years ago

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 commented 20 years ago

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 commented 20 years ago

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 commented 20 years ago

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​::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 commented 20 years ago

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​::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 commented 20 years ago

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 commented 20 years ago

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 commented 20 years ago

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 commented 20 years ago

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​://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 commented 20 years ago

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 commented 20 years ago

From perl_dummy@bloodgate.com

Inline Patch ```diff 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 commented 20 years ago

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 commented 20 years ago

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