Difference between revisions of "Math::BigInt"
Jump to navigation
Jump to search
| Line 30: | Line 30: | ||
=Converting a binary string to a BigInt= | =Converting a binary string to a BigInt= | ||
| − | + | This code conveniently reinterprets raw bytes as [[hexadecimals|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"; | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
=See Also= | =See Also= | ||
* [http://search.cpan.org/~tels/Math-BigInt-1.75/lib/Math/BigInt.pm CPAN] | * [http://search.cpan.org/~tels/Math-BigInt-1.75/lib/Math/BigInt.pm CPAN] | ||
Revision as of 10:28, 8 April 2005
Use
Specifying lib forces a library, but if that library isn't installed, fallback is automatic.
use Math::BigInt lib => 'GMP';
In-place Modification
Modification is in-place, regardless of context. A new object is not created for a result.
use Math::BigInt; # Void context my $a = new Math::BigInt '27'; $a->badd(3); print "$a"; # 30 # Scalar context my $b = new Math::BigInt '27'; my $c = $b->badd(3); print "$b"; # 30 print "$c"; # 30 print $b == $c ? "Same object" : "Not same object"; # Same object
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";