Skip Menu |

This queue is for tickets about the Math-BigInt CPAN distribution.

Report information
The Basics
Id: 62764
Status: resolved
Priority: 0/
Queue: Math-BigInt

People
Owner: Nobody in particular
Requestors: peter.john.acklam [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in:
  • 1.76
  • 1.77
  • 1.78
  • 1.79
  • 1.80
  • 1.82
  • 1.83
  • 1.84
  • 1.85
  • 1.86
  • 1.87
  • 1.88
  • 1.89
  • 1.90
  • 1.91
  • 1.92
  • 1.93
  • 1.95
  • 1.96
Fixed in: (no value)



Subject: bcmp() fails for very large numbers
bcmp() fails for very large numbers. In the case below, $x and $y are different, yet bcmp() returns 1, as if they were equal. The bug was introduced in version 1.76. perl -MMath::BigFloat -wle ' $x = Math::BigFloat -> new("1e1234567890987654321"); $y = Math::BigFloat -> new("1e1234567890987654300"); print $x -> bcmp($y)' The bug is caused by a short-cut in bcmp() where the exponent is converted to a Perl scalar (with the _num() library function). This causes a loss of precision. It seems that this is done deliberately, since a comment in the code says "the numify somewhat limits our length, but makes it much faster". I vote for following the good rules in the "GOALS" file in the distribution, one of which says "Favour correctness over speed".
Subject: Re: [rt.cpan.org #62764] bcmp() fails for very large numbers
Date: Sat, 6 Nov 2010 10:59:47 -0700
To: bug-Math-BigInt [...] rt.cpan.org
From: Jonathan Leto <jonathan [...] leto.net>
Howdy, I am a big fan of "correctness over speed". Is their some heuristic by which we can decide whether to convert the exponent to a scalar? It would suck to slow down the 99% case of the exponent fitting in a Perl scalar. Also, did you fork the Math::BigFloat repo on github yet, so you can send pull requests? Duke Show quoted text
> bcmp() fails for very large numbers. In the case below, $x and $y are > different, yet bcmp() returns 1, as if they were equal. The bug was > introduced in version 1.76. > > perl -MMath::BigFloat -wle ' > $x = Math::BigFloat -> new("1e1234567890987654321"); > $y = Math::BigFloat -> new("1e1234567890987654300"); > print $x -> bcmp($y)' > > The bug is caused by a short-cut in bcmp() where the exponent is > converted to a Perl scalar (with the _num() library function). This > causes a loss of precision. > > It seems that this is done deliberately, since a comment in the code > says "the numify somewhat limits our length, but makes it much faster". > I vote for following the good rules in the "GOALS" file in the > distribution, one of which says "Favour correctness over speed". >
-- Jonathan "Duke" Leto jonathan@leto.net http://leto.net
RT-Send-CC: jonathan [...] leto.net
On Sat Nov 06 14:00:11 2010, LETO wrote: Show quoted text
> Howdy,
Yo! :-) Show quoted text
> I am a big fan of "correctness over speed". Is their some > heuristic by which we can decide whether to convert the > exponent to a scalar? It would suck to slow down the 99% > case of the exponent fitting in a Perl scalar.
I haven't had time to really look into this yet, but I think it might be worth using _len() as a first comparison of the exponents. There is no need to compare the actual values of the exponents if they have different length. If the exponents have the same length, I'm not yet sure what to do. Perhaps use _str() and do a string comparison? Or use _acmp()? The worst thing is returning the wrong value silently, i.e., without a warning or error message. Show quoted text
> Also, did you fork the Math::BigFloat repo on github yet, so you can > send pull requests?
I have forked, cloned, branched, hacked, pushed, and sent 5 pull requests to Florian (rafl on github). They are my first pull requests, so I hope I did everything correctly. I am working on the bmodpow() and the blog() bugs, so more pull requests will come.
Status should be "patched" until a new release is out.
The bug is indeed present, but the initial bug report is incorrect. In that report, bcmp() returns 1 because $x is larger than $y, which is correct. To see the bug, the exponents must be larger, although that depends on the support for 64 bit integers and long doubles. With "use64bitint" and "uselongdouble" disabled, the following perl -MMath::BigFloat -wle ' $x = Math::BigFloat -> new("1e123456789098765432101234"); $y = Math::BigFloat -> new("1e123456789098765432101233"); print $x -> bcmp($y)' prints 0, indicating that $x and $y are equal. The correct should be 1. Anyway, this is fixed in the Math-BigInt distribution version 1.991.