Table of Contents
Implements an arbitrary precision integer arithmetic library. Uses gmp or bcmath, if available, and an internal implementation, otherwise. Here's an example:
<?php include('Math/BigInteger.php'); $a = new Math_BigInteger(2); $b = new Math_BigInteger(3); $c = $a->add($b); echo $c->toString(); // outputs 5 ?>
If you're running PHP 5, Math_BigInteger's only dependancy is the PCRE extension (which is enabled by default). Math_BigInteger also works on PHP 4 if PHP/Compat/Function/array_fill.php and PHP/Compat/Function/bcpowmod.php are included.
The constructor takes two parameters. The first is the number and the second represents the base. Both are optional (if they're not provided, the Math_BigInteger object will assume a value of 0).
The supported bases are base-2, base-10 (default), base-16, and base-256. To set $a, in the
above example, to 2, using base-2, we'd do new Math_BigInteger('10', 2)
. To do it using
base-16, you could do new Math_BigInteger('2', 16)
or new Math_BigInteger('0x2', 16)
.
To set it to 2 using base-256, you'd do new Math_BigInteger(chr(2), 256)
.
If the base is negative (eg. -256), two's compliment will be used. Thus, new Math_BigInteger(chr(0xFF), -256)
is equal to -1, as is new Math_BigInteger('0xFFFFFFFF', -16)
and new Math_BigInteger('11', -2)
.
Basically, if the leading bit is 1, the number is assumed to be negative.
toString()
returns the base-10 form of a number. toBytes()
returns the base-256
form of a number, toHex()
returns the base-16 form, and toBits()
the base-2 form.
toBytes()
, toHex()
, and toBits()
also take an optional parameter which,
if set, will return the two's compliment of a number. So if, for example, $a is equal to -1,
toBytes(true)
will return chr(0xFF)
.
On PHP 5, toString()
is called automatically when used in a string context via the
__toString() magic method.
subtract()
and multiply()
operate similarly to add()
. divide()
,
however, does not. Namely, it returns an array whose first element contains the quotient and whose
second element contains the "common residue". If the remainder would be positive, the "common residue"
and the remainder are the same. If the remainder would be negative, the "common residue" is equal to
the sum of the remainder and the divisor (basically, the "common residue" is the first positive modulo).
Here's an example:
<?php include('Math/BigInteger.php'); $a = new Math_BigInteger('10'); $b = new Math_BigInteger('20'); list($quotient, $remainder) = $a->divide($b); echo $quotient->toString(); // outputs 0 echo "\r\n"; echo $remainder->toString(); // outputs 10 ?>
Examples of each follow:
<?php include('Math/BigInteger.php'); $a = new Math_BigInteger('10'); $b = new Math_BigInteger('20'); $c = new Math_BigInteger('30'); $c = $a->powMod($b, $c); echo $c->toString(); // outputs 10 ?>
<?php include('Math/BigInteger.php'); $a = new Math_BigInteger(30); $b = new Math_BigInteger(17); $c = $a->modInverse($b); echo $c->toString(); // outputs 4 ?>
extendedGCD()
returns an array containing three Math_BigInteger values indexed with x, y,
and gcd. x and y represent Bézout's identity. gcd()
returns a Math_BigInteger value
equal to the gcd. An example of each follows:
<?php include('Math/BigInteger.php'); $a = new Math_BigInteger(693); $b = new Math_BigInteger(609); extract($a->extendedGCD($b)); $c = $a->gcd($b); echo $gcd->toString() . "\r\n"; // outputs 21 echo $c->toString() . "\r\n"; // outputs 21 echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21 ?>
$x->equals($y)
returns true or false depending on whether or not $x
and
$y
are equal.
$x->compare($y)
returns 1 if $x > $y, 0 if $x == $y, and -1 if $x < $y. The reason for this
is demonstrated thusly:
$x > $y: $x->compare($y) > 0 $x < $y: $x->compare($y) < 0 $x == $y: $x->compare($y) == 0 $x >= $y: $x->compare($y) >= 0 $x <= $y: $x->compare($y) <= 0
As a consequence of this, !$x->compare($y)
does not mean $x != $y
but rather
$x == $y
.
Some bitwise operations give different results depending on the precision being used. Examples include left shift, not, and rotates, as discussed for bitwise_not(). This function lets you control the precision.
Whenever a new Math_BigInteger object is created it's precision is set to the same precision as the
calling object. In other words, if you do $b = $a->bitwise_not()
then $b
will
have the same precision as $a
.
bitwise_and()
, bitwise_or()
and bitwise_xor()
operate similar to
add()
. bitwise_not()
is a bit more complicated. To elaborate, if the
precision (see setPrecision) is arbitrary,
$x->bitwise_not()
will always yield a smaller value since the most significant bit is
assumed to have a value of one. With fixed precision, however, the leading bit can be anything.
$a->bitwise_rightShift($shift)
shifts $a by $shift bits, effectively dividing by 2**$shift.
$a->bitwise_leftShift($shift)
shifts $a by $shift bits, effectively multiplying by 2**$shift.
$a->bitwise_rightRotate($shift)
and $a->bitwise_leftRotate($shift)
are
demonstrated thusly:
<?php include('Math/BigInteger.php'); $a = new Math_BigInteger('00111000', 2); $a->setPrecision(8); $b = $a->bitwise_leftRotate(2); echo $b->toBits(); // returns 11100000 echo "\r\n"; $a = new Math_BigInteger('00111000', 2); $b = $a->bitwise_leftRotate(2); echo $b->toBits(); // returns 100011 ?>
Just as with bitwise_not(), these operations are precision dependant.
Sets the random generator. To set it to mt_rand()
(which is what it is by default), call
$x->setRandomGenerator('mt_rand')
.
random($min, $max)
generates a random number between $min
and $max
.
randomPrime($min, $max)
generates a random prime number between $min
and $max
.
If no prime number exists between $min
and $max
false is returned.
randomPrime()
has an optional third parameter, as well - $timeout. Generating prime numbers
is a particurarly expensive operation and although in certain environments even 512-bit primes can be
generated in a less than a second it can take other environments upwards of around a minute if not more.