skip to Main Content
<script>
function hs(e, n) {
    return e * n % e;
}
alert(hs(1752865668, 1716717484170));
//result:  1752622684 
</script>

<?php
function hs($e, $n) {
    return $e * $n % $e;
}
echo hs(1752865668, 1716717484170);
//result: 386969652
?>

Both results are different because of their different 53-bit & 32-bit integer range. How can I have the same result that JS calculated in PHP in this senario? (Without using GMP: GNU Multiple Precision) (Using PHP 8+)

In short: I need the PHP code snippet that exactly shows the same result as JS.

Thank you!

2

Answers


  1. Both results are incorrect because the they exceed the max integer for both languages also in a 64 bit enviroment:

    $large_number = 9223372036854775807;
    var_dump($large_number);                     //int(9223372036854775807)
    $large_number = 9223372036854775808;
    var_dump($large_number);                     //float(9.2233720368548E+18)
    
    console.log(Number.MAX_SAFE_INTEGER);        //9007199254740991
    
    Login or Signup to reply.
  2. function hs($e, $n) {
        return bcmod(sprintf('%f', $e * $n), $e);
    }
    

    This code gives me the same result, it needs the BCMath extension.


    Explanation: Firstly, I found the following facts

    BigInt(1752865668 * 1716717484170)      = 3009175139656926232576
    1716717484169 * 1752865668 + 1752622684 = 3009175139656926232576
    

    But the precise result should be 3009175139656926475560, so I realized that JavaScript may perform a modulo operation on a double floating number.

    But PHP always converts the operands to integers. However the result of $e * $n here has exceeded the range of 64-bit integer, so another way of calculation is needed. Coincidentally, the BCMath extension meets the criteria. The extension requires operands to be strings in integer form, while sprintf converts floating numbers to their integral representations.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search