开发者

Getting different results in PHP and JS when bit shifting

I'm getting some odd results where 2 identical functions (one in PHP and one in javascript) are returning different results.

The input for both of these lines of code is identical:

a = 4653896912;
b = 13;

I have double checked the variable types and both variables are numbers in JS and integers in PHP.

The line of code for PHP is this:

$a = $a >> $b;

For Javascript it's this:

a = a >> b;

You'd expect a to have the same value after both, but I'm getting the following:

PHP: $a = 568102
JS: a = 43814

Which has completely baffled me at this point.


Turns out this is definitely an issue of PHP usin开发者_StackOverflow社区g 64 bit integers and JS only using 32 bit. The problem I face now is that I need to get PHP to use 32-bit integers for these calculations. I found a function someone else wrote that looks like it should work, but it doesn't seem to be changing the output at all for me.

private static function toInt32(&$x) {
    $z = hexdec(80000000);
    $y = (int) $x;
    if($y ==- $z && $x <- $z){
        $y = (int) ((-1) * $x);
        $y = (-1) * $y;
    }
    $x = $y;
}


The below code demonstrates masking the upper 32 bits of the number to retrieve only the lower 32 bits to use in your calculations. 4294967295 is 2^32 - 1. I think that if you mask all values that could be greater than 32 bits in this manner, then you can get the same results from your php and javascript.

<?php
    $php_a = 4653896912;
    $php_b = 13;

    //convert $php_a into a 32 bit val
    $php_a = $php_a & 4294967295;

    $a = $php_a >> $php_b;
    echo "PHP: \$a = $a <br />";
?>
<script type="text/javascript">
    var a = 4653896912;
    var b = 13;

    var a = a >> b;
    alert('Javascript A value is ' + a);
</script>


4653896912 is more than 32 bits.. unpredictable results are likely. I get $a = 43814 for PHP, but that is actually 358929617 >> 13, so in all likelihood PHP is doing 64 bit operations but JavaScript is only 32 bit.


I believe it's because you're a is above the limit of a 32-bit signed integer for [PHP][1].

The highest value possible is about 2 million, and a is over 4 billion.

When you're rolling over because of space limitations, results can be unpredictable (or at least, very difficult to figure out).

If your server is on a 64-bit version of PHP then it'll max out much higher than than, but javascript is limited by what the end-user is running.

You can read up on PHP on their integers page.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜