|
|
Line 1: |
Line 1: |
| | | |
− |
| |
− | =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.
| |
− |
| |
− | <nowiki>
| |
− | use Math::BigInt;
| |
− |
| |
− | # Apparently part of this program got lost.
| |
− | # Will try to find it later. -- PSM
| |
− |
| |
− | 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";
| |
− | </nowiki>
| |
− |
| |
− | ==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=
| |
− |
| |
− | 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=
| |
− |
| |
− | * [http://search.cpan.org/~tels/Math-BigInt-1.75/lib/Math/BigInt.pm CPAN]
| |