Получение разных результатов в PHP и JS при сдвиге битов - PullRequest
0 голосов
/ 11 февраля 2011

Я получаю некоторые странные результаты, когда 2 идентичные функции (одна в PHP и одна в javascript) возвращают разные результаты.

Ввод для обеих этих строк кода идентичен:

a = 4653896912;
b = 13;

Я дважды проверил типы переменных, и обе переменные являются числами в JS и целыми числами в PHP.

Строка кода для PHP выглядит так:

$a = $a >> $b;

Для Javascript это так:

a = a >> b;

Вы ожидаете, что a будет иметь одинаковое значение после обоих, но я получаю следующее:

PHP: $a = 568102
JS: a = 43814

Что полностью смутило меня в этот момент.


Оказывается, это определенно проблема PHP, использующего 64-битные целые числа, а JS - только 32-битные. Проблема, с которой я сталкиваюсь сейчас, заключается в том, что мне нужно заставить PHP использовать 32-битные целые числа для этих вычислений. Я нашел функцию, написанную кем-то другим, которая выглядит так, как будто она должна работать, но она, похоже, не меняет вывод для меня.

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;
}

Ответы [ 3 ]

0 голосов
/ 11 февраля 2011

Я полагаю, это потому, что вы a превышают предел 32-битного целого числа со знаком для [PHP] [1].

Максимально возможное значение составляет около 2 миллионов, а a превышает 4 миллиарда.

Когда вы переворачиваетесь из-за нехватки места, результаты могут быть непредсказуемыми (или, по крайней мере, очень сложными для определения).

Если ваш сервер работает на 64-битной версии PHP, его максимальная скорость будет намного выше, чем у, но JavaScript ограничен тем, что работает конечный пользователь.

Вы можете прочитать о PHP на странице целых чисел .

0 голосов
/ 11 февраля 2011

Приведенный ниже код демонстрирует маскирование старших 32 битов числа для извлечения только младших 32 бит для использования в ваших вычислениях. 4294967295 - 2 ^ 32 - 1. Я думаю, что если вы замаскируете таким образом все значения, которые могут быть больше 32 бит, то вы можете получить те же результаты из вашего php и 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>
0 голосов
/ 11 февраля 2011

4653896912 превышает 32 бита. Возможны непредсказуемые результаты. Я получаю $a = 43814 для PHP, но на самом деле это 358929617 >> 13, поэтому, по всей вероятности, PHP выполняет 64-битные операции, а JavaScript только 32-битный.

...