Difference between revisions of "Math::BigInt"
(→Use) |
|||
Line 5: | Line 5: | ||
use Math::BigInt lib => 'Pari,GMP,BitVect'; | use Math::BigInt lib => 'Pari,GMP,BitVect'; | ||
− | =In-place Modification= | + | =In-place vs. Copy Modification= |
− | + | Whether Math::BigInt does its thing in-place or not depends on whether you use the methods or the overloaded operators. | |
+ | |||
+ | ==Methods Work In-Place== | ||
+ | |||
+ | If you use the methods, modification is in-place, regardless of context. A new object is not created for a result. | ||
use Math::BigInt; | use Math::BigInt; | ||
+ | |||
+ | # This reblessing isn't fail-safe | ||
+ | # but it works for this example | ||
+ | sub same_object ($$) { | ||
+ | my $pa = ref($_[0]) or return undef; | ||
+ | my $pb = ref($_[1]) or return undef; | ||
+ | my $v; | ||
+ | bless $_[0], 'Xana::Fake'; | ||
+ | bless $_[1], 'Xana::Fake'; | ||
+ | $v = $_[0] == $_[1]; | ||
+ | bless $_[1], $pb; | ||
+ | bless $_[0], $pa; | ||
+ | $v; | ||
+ | } | ||
# Void context | # Void context | ||
− | |||
my $a = new Math::BigInt '27'; | my $a = new Math::BigInt '27'; | ||
$a->badd(3); | $a->badd(3); | ||
− | + | $a == '30' | |
− | + | or die "a=$a"; | |
# Scalar context | # Scalar context | ||
− | |||
my $b = new Math::BigInt '27'; | my $b = new Math::BigInt '27'; | ||
my $c = $b->badd(3); | my $c = $b->badd(3); | ||
+ | $b == '30' | ||
+ | or die "b=$b"; | ||
+ | same_object($b,$c) | ||
+ | or die "b and c are not the same object"; | ||
+ | |||
+ | ==Overloads Use Copies== | ||
+ | |||
+ | Meanwhile, overloaded operators treat the objects like regular scalars; nothing is modified in place unless an assignment operator (including <code>+=</code>, <code>*=</code>, ''etc.'', but not <code>=</code> for Perl reasons) is used. | ||
+ | |||
+ | # Void context using overloads | ||
+ | # does not work in-place | ||
+ | my $d = new Math::BigInt '57'; | ||
+ | $d + 3; | ||
+ | $d == '57' | ||
+ | or die "d=$d"; | ||
− | + | # Scalar context using overloads | |
− | + | # does not work in-place | |
− | + | my $e = new Math::BigInt '97'; | |
− | + | my $f = $e + 4; | |
+ | $e == '97' | ||
+ | or die "e=$e"; | ||
+ | $f == '101' | ||
+ | or die "f=$f"; | ||
=Converting a binary string to a BigInt= | =Converting a binary string to a BigInt= |
Revision as of 12:50, 8 April 2005
Contents
Use
Specifying lib
forces a library, but if that library isn't installed, fallback is automatic.
use Math::BigInt lib => 'Pari,GMP,BitVect';
In-place vs. Copy Modification
Whether Math::BigInt does its thing in-place or not depends on whether you use the methods or the overloaded operators.
Methods Work In-Place
If you use the methods, modification is in-place, regardless of context. A new object is not created for a result.
use Math::BigInt; # This reblessing isn't fail-safe # but it works for this example sub same_object ($$) { my $pa = ref($_[0]) or return undef; my $pb = ref($_[1]) or return undef; my $v; bless $_[0], 'Xana::Fake'; bless $_[1], 'Xana::Fake'; $v = $_[0] == $_[1]; bless $_[1], $pb; bless $_[0], $pa; $v; } # Void context my $a = new Math::BigInt '27'; $a->badd(3); $a == '30' or die "a=$a"; # Scalar context my $b = new Math::BigInt '27'; my $c = $b->badd(3); $b == '30' or die "b=$b"; same_object($b,$c) or die "b and c are not the same object";
Overloads Use Copies
Meanwhile, overloaded operators treat the objects like regular scalars; nothing is modified in place unless an assignment operator (including +=
, *=
, etc., but not =
for Perl reasons) is used.
# Void context using overloads # does not work in-place my $d = new Math::BigInt '57'; $d + 3; $d == '57' or die "d=$d"; # Scalar context using overloads # does not work in-place my $e = new Math::BigInt '97'; my $f = $e + 4; $e == '97' or die "e=$e"; $f == '101' or die "f=$f";
Converting a binary string to a BigInt
This code conveniently reinterprets raw bytes as hexadecimal digits, big-endian style, so that the data may be cast into a bigint. This code doesn't do any buffering; for that, try my new Xana::Math::RawDataUtil module in Xana.
# Unsigned my $a = "ZYXWVUT"; my $ba = new Math::BigInt '0x' . unpack('H*',$a); # Test $ba == '25430983861228884' or die "ba=$ba"; # Signed sub raw_to_signed_bigint ($) { # The MSB is the sign bit. if(unpack('C',substr($_[0],0,1)) & 0x80) { my $hex = unpack('H*',$_[0]); # Invert the hex digits. $hex =~ tr/0123456789aAbBcCdDeEfF/fedcba9876554433221100/; my $bigint = new Math::BigInt "0x$hex"; # Then, the ones complement is the right answer. return $bigint->bnot(); } else { # The normal unsigned thing. return Math::BigInt->new( '0x' . unpack('H*',$_[0]) ); } } # Tests my $bb = raw_to_signed_bigint "\xFF\x54\xAB\x56\x73\x14\xE0\xF5\x2E"; $bb == '-12345678901234567890' or die "bb=$bb"; my $bc = raw_to_signed_bigint "\xFF"; $bc == '-1' or die "bc=$bc"; my $bd = raw_to_signed_bigint "ZYXWVUT"; $bd == '25430983861228884' or die "bd=$bd";