Wiimm
Wiimm

Reputation: 3562

Integer (64-bit) division of large numbers without using intdiv() (before php7)

Tests are made at 64-bit system!

php7 has a nice function: intdiv(). The following code works perfect:

$number = 0x7fffffffffffffff;
$result = intdiv($number,62);

The result is 148764065110560900 (remainder 7) like expected.

But how do I this division in php<7 (e.g. php5.3)?

$number = 0x7fffffffffffffff;
$result = intval($number/62);

Here, the result is 148764065110560896, smaller than the result of intdiv(...). The reason is clear: $number/62 is a floating point operation. So $number is converted to a float and looses precision (52 instead of 64 bits). So the result is rounded down.

Code to proof:

php -r '$a=0x7fffffffffffffff; $b=intdiv($a,62); $c=intval($a/62); printf("%d - %d = %d\n",$b,$c,$b-$c);'
// result: 148764065110560900 - 148764065110560896 = 4

My question: Does anyone knows a function, that returns the correct integer value for e.g. 0x7fffffffffffffff/62 without using intdiv()?

Solution based on answer by trincot

if (!function_exists('intdiv'))
{
    function intdiv($a,$b)
    {
        $a = intval($a);
        $b = intval($b);
        return ( $a - $a % $b ) / $b;
    }
}

I'll plan more tests to verify this replacement function.

Upvotes: 2

Views: 363

Answers (2)

FrancescoMM
FrancescoMM

Reputation: 2960

Just adding that, if in case you need more precision, you can consider Arbitrary Precision Mathematics, BCMath:

$res=bcdiv($number , "62", 255);

148764065110560900.112903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451612903225806451

Upvotes: 0

trincot
trincot

Reputation: 350477

You can use the % operator to get the remainder. Then after subtraction of the remainder perform the division:

$rem = $number % 62;
$result = ($number - $rem) / 62;

Upvotes: 2

Related Questions