Правильное двоичное представление для PHP_INT_MAX + 1, с которым выполняются побитовые операции в PHP?

0

Согласно этому сообщению → Как получить двоичное представление числа с плавающей запятой в PHP?

функция floatToBinStr ($ value) используется для представления float/double в двоичном выражении в PHP. Если я вызову его с помощью этого параметра:

floatToBinStr(PHP_INT_MAX + 1);

Я получаю это двоичное представление:

0100001111100000000000000000000000000000000000000000000000000000

64 бит, самый левый бит - 63-й бит, так как 64-й бит используется для отрицательных поплавков, все работает нормально.

У меня есть функция, которая возвращает позицию самого левого бита, установленную на один заданный параметр number, и я заметил, что если я передам значения, большие, чем PHP_INT_MAX (например)

 public function getPositionOfLeftMostBitSetTo1($n) {
    $masks = array(0x1, 0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000, 0xFFFFFFFF00000000);
    $positions = array(1, 2, 2, 4, 8, 16, 32);
    $r = ($n < 0) ? -1 : 0);
    for ($i = PHP_INT_SIZE == 8 ? 6 : 5; $i >= 0; $i--)
    {
      if ($n & $masks[$i]) {
            $n >>= $positions[$i];
            $r += $positions[$i];
        }
    }
    return $r;
 }
 echo getPositionOfLeftMostBitSetTo1(PHP_INT_MAX + 1);

Я получаю 65 в качестве вывода. Если я попробую:

echo decbin(PHP_INT_MAX + 1); // PHP_INT_MAX + 1 = 9.22337203685E+18

Я получаю это

1000000000000000000000000000000000000000000000000000000000000000

Таким образом, похоже, что самый старший бит - это 64-й, хотя это неверно, потому что это не отрицательный float, и моя функция не возвращается должным образом и вместо этого возвращает 65, потому что она действует так, как будто она сдвигается вправо на отрицательном ква...

Как я могу заставить PHP распознавать float/doubles больше, чем PHP_INT_MAX, как они должны, и выполнять безопасные побитовые операции над ними?

Спасибо за внимание!

Теги:
floating-point
bit-manipulation
double
shift

1 ответ

0
Лучший ответ

Я решил преобразовать float в двоичный код с функцией floatToBinStr ($ value), а затем я использовал bindec для преобразования этого двоичного представления в целое число, на которое я могу сместиться без каких-либо проблем, в конце концов цель getPositionOfLeftMostBitSetTo1() - вернуть позиция самого левого бита установлена на единицу, больше ничего, поэтому преобразование этого двоичного поплавка в любое целое было бы выполнено.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню