Skip Menu |
 

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

Report information
The Basics
Id: 16221
Status: resolved
Worked: 5 min
Priority: 0/
Queue: Math-BigInt

People
Owner: TELS [...] cpan.org
Requestors: bpphillips [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: (no value)
Fixed in: (no value)



Subject: overloading and foreign objects
Download (untitled) / with headers
text/plain 626b
The following test case fails: package main; use Test::More tests => 1; use Math::BigInt; my $int = Math::BigInt->new(10); my $percent = My::Percent->new(100); is($int * $percent,10); package My::Percent; sub new { my $class = shift; my $num = shift; return bless \$num, $class; } sub as_number { my $self = shift; return Math::BigInt->new($$self / 100); } sub as_string { my $self = shift; return $$self; } The bug is on line 2350 of Math::BigInt: $k->can('as_number') ? $k = $k->as_number() : $k = $a[0]->new($k); Should be: $k = $k->can('as_number') ? $k->as_number() : $a[0]->new($k);
Download (untitled) / with headers
text/plain 455b
On Wed Nov 30 16:42:55 2005, guest wrote: Show quoted text
> The following test case fails:> > The bug is on line 2350 of Math::BigInt: > $k->can('as_number') ? $k = $k->as_number() : $k = $a[0]->new($k); > > Should be: > $k = $k->can('as_number') ? $k->as_number() : $a[0]->new($k);
Thanx for your report! However, when I make the proposed change, some testcases fail, so I have to investigate what the real fix should be. Sorry for the delay! Best wishes, Tels
Download (untitled) / with headers
text/plain 493b
The code line $k->can('as_number') ? $k = $k->as_number() : $k = $a[0]->new($k); is bad. It doesn't do what people (most likely) think. It *looks* like it is equivalent to $k->can('as_number') ? ($k = $k->as_number()) : ($k = $a[0]->new($k)); but it isn't. The reason, I believe, is that "… = …" has *lower* precedence than "… ? … : …". From what I understand, the net result is always that $k = $a[0]->new($k). That part of Math::BigInt::objectify() should be investigated.
Download (untitled) / with headers
text/plain 1.7k
On Sun Jan 28 07:47:37 2007, TELS wrote: Show quoted text
> > Thanx for your report! However, when I make the proposed change, some > testcases fail, so I have to investigate what the real fix should be.
In the line in Math::BigInt::objectify() saying $k->can('as_number') ? $k = $k->as_number() : $k = $a[0]->new($k); the "$k = $a[0]->new($k)" is always executed. If the test "$k->can('as_number')" is true, the "$k->as_number()" is also executed, but has no effect, since $k has already been through "$k = $a[0]->new($k)". When the above line is changed to $k = $k->can('as_number') ? $k->as_number() : $a[0]->new($k); the "$k->as_number()" is executed without $k having been through "$k = $a[0]->new($k)". The tests fail, as mentioned by TELS, because "$k->as_number()" and "$a[0]->new($k)" doesn't always give the same results. So Math::Big* has inconsistent behaviour with respect to how a Math::BigSomething is converted to a Math::BigInt. For example, try to convert a Math::BigFloat to a Math::BigInt: $ perl -MMath::BigFloat -wle '$x = Math::BigFloat -> new("3.14"); print Math::BigInt -> new($x)' NaN $ perl -MMath::BigFloat -wle '$x = Math::BigFloat -> new("3.14"); print $x -> as_number()' 3 (Even Math::BigInt->new() itself isn't consistent; see http://rt.cpan.org/Public/Bug/Display.html?id=61887) I suggest that "Math::BigInt -> new()" is fixed so that it always returns the same as Math::BigSomething -> as_number(), or CORE::int(). This might cause some backwards incompatibility if people have written code depending on "Math::BigInt -> new()" returning a NaN if the input has a non-zero decimal part (which it not always does; see RT 61887), but I think it is worth it. And since we are on the doorstep of Math::BigInt version 2.00, this is a good time to make the change.
RT-Send-CC: nospam-abuse [...] bloodgate.com
Download (untitled) / with headers
text/plain 1.1k
The same problem appears with Math::BigFloat. Here is a test that fails: Show quoted text
________________________________________ package main; use Test::More tests => 1; use Math::BigFloat; my $float = Math::BigFloat->new(10); my $percent = My::Percent->new(100); is($float * $percent, 10); package My::Percent; sub new { my $class = shift; my $num = shift; return bless \$num, $class; } sub as_int { my $self = shift; return Math::BigInt->new($$self / 100); } sub as_float { my $self = shift; return Math::BigFloat->new($$self / 100); } sub as_string { my $self = shift; return $$self; }
________________________________________ The problem is with Math::BigInt::objectify(). The objectify() function shouldn't really be in Math::BigInt. Both Math::BigInt, Math::BigFloat, and Math::BigRat uses Math::BigInt::objectify(), but Math::BigFloat and Math::BigRat are not subclasses of Math::BigInt, so things go wrong. The objectify() function should probably have been in a common parent class for the three Math::Big* modules (together with the other common functions/methods round_mode(), upgrade(), downgrade(), ...).
The code has been changed, and the test case passes. Please close this ticket.
Fixed


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.