Math::BigInt

From HalfgeekKB
Jump to navigation Jump to search

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";

See Also