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
The bignum module changes behavior of Math::BigInt::bdiv() #9937
Comments
From jl_post@hotmail.comCreated by jl_post@hotmail.comThe documentation in "perldoc Math::BigInt" says that $x->bdiv($y); will change the value of $x. That is exactly what I #!/usr/bin/perl use strict; use Math::BigInt; print "\$n before \$n->bdiv(2): $n\n"; # prints 6 # use bignum; __END__ The output I get (on both Linux and Strawberry Perl $n before $n->bdiv(2): 6 Nothing wrong here. (This is exactly what I expect to see.) However, if I uncomment the "use bignum;" line (that last $n before $n->bdiv(2): 6 Notice that now the second line says that $n is 6. Evidently just the inclusion of the "bignum" module is causing I haven't found any other methods that are affected So the bug is that simply declaring "use bignum;" Perl Info
|
From @pjfOn Thu Oct 29 10:21:18 2009, jl_post@hotmail.com wrote:
Ouch! Nice catch, that looks like a nasty bug. I can confirm it's I'm marking this as something that needs attention in 5.12.0. Giving Thanks again for the bug report, it's very much appreciated! Paul -- |
The RT System itself - Status changed from 'new' to 'open' |
From @TJCI confirmed this bug still exists in 5.11.1 |
From @iabynOn Thu, Oct 29, 2009 at 10:21:18AM -0700, jl_post@hotmail.com (via RT) wrote:
[snip]
It's actually a big in BigInt.pm or BigFloat.pm; the 'use bignum' just use Math::BigInt; my $fn = Math::BigInt->new(6); print "result (should be 3): $fn\n"; Jesse, given that Big* are CPAN modules and that this bug is present in Also, does anyone know if there's a way to transfer this to the -- |
From @obraOn Wed Jan 20 14:13:43 2010, davem wrote:
It's not a regression, but I was certainly happy to take PJF's assertion Bugs in dual-lifed modules can certainly be showstoppers if they're nasty enough. Doing my own
There is not. We've been talking to perl.org about merging the two, but we're not there yet. |
From @nwc10On Wed, Jan 20, 2010 at 10:13:10PM +0000, Dave Mitchell wrote:
I've been rather hoping that sd could be taught how to do this http://syncwith.us/sd/ Nicholas Clark |
From @xdgOn Wed, Jan 20, 2010 at 5:19 PM, Jesse via RT <perlbug-followup@perl.org> wrote:
One could forward the original email to the right RT queue at David |
From @obraBased on previous discussion and input from former pumpkings, I'm removing |
Back in October 2009 it was reported,
There was discussion as to the real cause of the problem. I reported this problem upstream today at https://rt.cpan.org/Ticket/Display.html?id=150252. @pjacklam, can you take a look? Thanks. |
The underlying cause here is upgrading and downgrading. Unlike the Here is what happens: Division is an operation that might return a non-integer. So when upgrading is enabled in Math::BigInt, the division is handed over to the upgrade class. By default, Math::BigInt upgrades to Math::BigFloat. So it is Math::BigFloat that performs the division, using Math::BigFloat objects. When Math::BigFloat has performed a division, and downgrading is enabled, Math::BigFloat checks the result to see if it is an integer, and if it is, the result is passed to the downgrade class. By default, Math::BigFloat downgrades to Math::BigInt. So the final result is a Math::BigInt object. However, it will be a different object than the original invocand object. The same thing happens with every Math::BigInt method that might return a non-integer, not just
I think the best solution is to improve the documentation and make it clear that this will happen, and why. The only way to make sure that the ¹ There were a few releases of |
@pjacklam, thank you for that explanation. I appreciate the time and effort you had to put into researching it.
Yes, I think that some documentation about the existence of weird corner cases would be good. |
But this is exactly what already happens with:
I personally think that's the correct behaviour, and I would expect that the exact same thing would happen with:
But if we want to use bdiv() we instead need to do:
To make it worse, these method calls will modify-in-place the object's value if there's no upgrading involved, but won't modify-in-place the value if upgrading is involved,
This is all goes on silently, does not DWIM, and requires that the programmer be alert to these issues. I know that ships have sailed and bridges have been burnt. @pjacklam, if it's impractical to make any behavioural changes, then I agree that the bignum docs should prominently set out the perils of using the method calls. Cheers, |
You got me there. I didn’t expect that. It must be perl itself that takes care of this, because
When I look at the addresses, I see that they change:
I agree. I think the fact that
Right. The code is full of cases like
Yes, I am aware of this. I believe the idea is that when you use
I have been thinking about this, and I believe it is not as difficult to implement as I originally though. The question is how many other modules will break if I make this change. :-) |
Yes, I expect that's the usual practice. Otherwise there would surely have been more complaints about this issue than just this one report from 14 years ago.
I actually think not many, if any, breakages will occur. (Easy for me to say, I know ;-) But code like (BTW, I've been allowing cross-class overloading between my Math::GMPz, Math::GMPq and Math::MPFR modules for a while now - for reasons of "fun" rather than "usefulness". Lately, I've enhanced these operations to allow "upgrading", but I don't do any "downgrading". Cheers, |
Migrated from rt.perl.org#70109 (status was 'open')
Searchable as RT70109$
The text was updated successfully, but these errors were encountered: