Skip Menu |

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

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

People
Owner: Nobody in particular
Requestors: DATA [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.89
Fixed in: 1.999718



Subject: band bxor bior don't work at all
danielt@nuts:~> pmvers Math::BigFloat 1.60 danielt@nuts:~> pmvers Math::BigInt 1.89 danielt@nuts:~> pmvers Math::BigInt::Calc 0.52 danielt@nuts:~> perl -MCarp::Always -MMath::BigFloat -E 'sub b { Math::BigFloat->new(shift) }; b(10)->band(b(5))' Can't use an undefined value as an ARRAY reference at /home/danielt/perl5/lib/perl5/Math/BigInt/Calc.pm line 1175 Math::BigInt::Calc::_acmp('Math::BigInt::FastCalc', undef, undef) called at /home/danielt/perl5/lib/perl5/Math/BigInt/Calc.pm line 2071 Math::BigInt::Calc::_and('Math::BigInt::FastCalc', undef, undef) called at /home/danielt/perl5/lib/perl5/Math/BigInt.pm line 2065 Math::BigInt::band('Math::BigFloat=HASH(0x8984818)', 'Math::BigFloat=HASH(0x8bc7180)') called at -e line 1 zsh: exit 255 perl -MCarp::Always -MMath::BigFloat -E danielt@nuts:~> perl -MCarp::Always -MMath::BigFloat -E 'sub b { Math::BigFloat->new(shift) }; b(10)->bxor(b(5))' Can't use an undefined value as an ARRAY reference at /home/danielt/perl5/lib/perl5/Math/BigInt/Calc.pm line 1175 Math::BigInt::Calc::_acmp('Math::BigInt::FastCalc', undef, undef) called at /home/danielt/perl5/lib/perl5/Math/BigInt/Calc.pm line 2106 Math::BigInt::Calc::_xor('Math::BigInt::FastCalc', undef, undef) called at /home/danielt/perl5/lib/perl5/Math/BigInt.pm line 2144 Math::BigInt::bxor('Math::BigFloat=HASH(0x8dde818)', 'Math::BigFloat=HASH(0x9021180)') called at -e line 1 zsh: exit 255 perl -MCarp::Always -MMath::BigFloat -E danielt@nuts:~> perl -MCarp::Always -MMath::BigFloat -E 'sub b { Math::BigFloat->new(shift) }; b(10)->bior(b(5))' Can't use an undefined value as an ARRAY reference at /home/danielt/perl5/lib/perl5/Math/BigInt/Calc.pm line 1175 Math::BigInt::Calc::_acmp('Math::BigInt::FastCalc', undef, undef) called at /home/danielt/perl5/lib/perl5/Math/BigInt/Calc.pm line 2142 Math::BigInt::Calc::_or('Math::BigInt::FastCalc', undef, undef) called at /home/danielt/perl5/lib/perl5/Math/BigInt.pm line 2105 Math::BigInt::bior('Math::BigFloat=HASH(0x86a3818)', 'Math::BigFloat=HASH(0x88e6180)') called at -e line 1 zsh: exit 255 perl -MCarp::Always -MMath::BigFloat -E
Subject: band bxor bior don't work with Math::BigFloats
Thank you for your report. I have dug into this, and it seems like this being yet another bug related to the internal function Math::BigInt::objectify(). In your case, the invocand is a Math::BigFloat, so you're trying to execute Math::BigFloat->band(), but that method does not exists, so Math::BigInt->band() takes over. That method calls objectify() to make sure that all arguments are objects, which they are, so the arguments fall right through objectify(). So now the guts of Math::BigInt->band() starts doing the actual work. However, that method, as most methods in the Math::Big(Int|Float|Rat) colletion, don't use high-level methods to access object information, but work directly on the objects' internal data structure. That fails, because Math::BigInt->band() assumes the objects are Math::BigInts, which they aren't. The objects are Math::BigFloats, which have a different internal data structure than Math::BigInts. In this case, Math::BigInt->band() is accessing the "value" key of the object's hash, but Math::BigFloats don't have that key, causing "undefs" to be passed to the underlying library Math::BigInt::Calc. I don't have a fix yet, but at least I see what is going wrong. By the way, I changed the subject from "band bxor bior don't work at all" to "band bxor bior don't work with Math::BigFloats".
This is still an issue: Show quoted text
>perl -MCarp::Always -MMath::BigFloat -E "sub b {
Math::BigFloat->new(shift) }; b(10)->band(b(5))" Can't use an undefined value as an ARRAY reference at C:/STRAWBERRY/perl/lib/Math/BigInt/Calc.pm line 1180. Math::BigInt::Calc::_acmp('Math::BigInt::Calc', undef, undef) called at C:/STRAWBERRY/perl/lib/Math/BigInt/Calc.pm line 2106 Math::BigInt::Calc::_and('Math::BigInt::Calc', undef, undef) called at C:/STRAWBERRY/perl/lib/Math/BigInt.pm line 2177 Math::BigInt::band('Math::BigFloat=HASH(0x774bb4)', 'Math::BigFloat=HASH(0x85b604)') called at -e line 1
Subject: [PATCH] band bxor bior don't work with Math::BigFloats
Perl converts floating point numbers to integers prior to performing bit operations ~ & | ^. I consider it reasonable for big floats to behave similarly to perl builtin numbers. This patch is a suggestion as how this could be implemented. The methods bnot, band, bior, bxor can act as thin wrappers for their integer variants. -Martin
Subject: Math-BigInt-1.9993-MHASCH-01.patch
diff -rup Math-BigInt-1.9993.orig/lib/Math/BigFloat.pm Math-BigInt-1.9993/lib/Math/BigFloat.pm --- Math-BigInt-1.9993.orig/lib/Math/BigFloat.pm 2014-04-04 12:07:22.000000000 +0200 +++ Math-BigInt-1.9993/lib/Math/BigFloat.pm 2015-04-28 15:01:14.000000000 +0200 @@ -467,6 +467,44 @@ sub bneg # $class->SUPER::bnot($class,@_); # } +# bit operations truncate big floats, just like Perl floats + +sub bnot + { + my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_); + return $x->as_number->bnot; + } + +sub band + { + my ($self,$x,$y) = (ref($_[0]),@_); + if (!$self || $self ne ref $y) + { + ($self,$x,$y) = objectify(2,@_); + } + return $x->as_number->band($y->as_number); + } + +sub bior + { + my ($self,$x,$y) = (ref($_[0]),@_); + if (!$self || $self ne ref $y) + { + ($self,$x,$y) = objectify(2,@_); + } + return $x->as_number->bior($y->as_number); + } + +sub bxor + { + my ($self,$x,$y) = (ref($_[0]),@_); + if (!$self || $self ne ref $y) + { + ($self,$x,$y) = objectify(2,@_); + } + return $x->as_number->bxor($y->as_number); + } + sub bcmp { # Compares 2 values. Returns one of undef, <0, =0, >0. (suitable for sort)
Fixed in Math-BigInt-1.999718.