Intereting Posts
CakePHP – поиск 3 таблиц с использованием JOIN Всегда показывать предыдущие и следующие ссылки с использованием класса разбиения на страницы CodeIgniter сортировка массива php Laravel db migration – renameColumn error – запрошено неизвестное имя типа базы данных Использование ini_set ("memory_limit", "-1") и все еще из памяти Дублировать уведомления Apple APNS push? PHP: Что означает & перед именем переменной? Как правильно настроить переменную среды PHP для запуска команд в Git Bash Правила корзины покупок с пользовательским условием? Проблемы с особыми символами MySQL Laravel перенаправляет маршрут, но затем apache дает ошибку 404 Валютный символ в пурпуре PHP. Как запретить пользователю входить в систему с нескольких компьютеров одновременно? Как долго должен быть мой пароль соли, и SHA-256 достаточно хорош? Пошаговое руководство. Как выполнить Xdebug по устранению неполадок подключения к IDE клиента

Почему правое смещение -1 всегда дает -1 в PHP?

Я пытаюсь понять, почему, если я смещаю отрицательное целое число -1, я всегда получаю -1, например:

echo -1 >> 64; // -1 echo -1 >> 5; // -1 echo -1 >> 43; // -1 echo -1 >> 1; // -1 

Какой бы ни был второй операнд правого сдвига, -1 остается -1 … Я понимаю, что когда вы выполняете правую смену, вы на самом деле делаете это:

x >> y = x / 2^y

Но в случае x, равного -1, если это так, я делаю:

-1 >> 3 = -1 / 2^3

Разве это значение не должно быть -1/8 = -0.125?

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

Related of "Почему правое смещение -1 всегда дает -1 в PHP?"

Операторы побитового сдвига не делятся. Они делают то, что они должны делать, – сдвигают биты. В частности, оператор правого сдвига выполняет следующее:

  • для каждого бита, начинающегося справа, установите его значение на то, что находится слева от него
  • для самого левого бита, который не имеет ничего слева, сохраните его текущее значение

Например, если ваш номер

 1011...101 

правая смена дает вам

 11011...10 

Таким образом, самый правый бит (LSB) теряется, а самый левый бит (MSB) дублируется. Это называется «распространение знака», поскольку MSB используется для выделения положительных (MSB = 0) из отрицательных (MSB = 1) чисел.

Отрицательные числа хранятся как «дополнение двух», то есть в 32-битной системе, -x хранится как 2^32-x . Итак, -110...00 (32 zeroes) - 1 == 1...1 (32 ones) . Если вы переместите 32 в соответствии с приведенной выше процедурой, вы снова получите 32, то есть -1 >> whatever что всегда будет -1 .

Разница между правым сдвигом и делением на два состоит в том, что сдвиг дает одинаковые результаты для нечетных и четных чисел. Так как самый правый бит потерян, когда вы смещаете нечетное число (которое имеет LSB = 1), результат будет таким же, как сдвиг следующего нижнего четного числа (одна и та же комбинация бит, но с LSB = 0). Таким образом, вы не получаете половинок при смене, так как дивиденд вынужден быть четным. Например,

10 10 = 1010 2 , 10/2 = 5,0 и 10 >> 1 == 5 10 == 101 2

11 10 = 1011 2 , 11/2 = 5,5, но 11 >> 1 == 5 10 == 101 2

Если вы предпочитаете думать о x >> 1 в терминах деления, он сначала «округляет» x до четного числа ( x - abs(x) % 2 ), а затем делит это число на два.

При x = -1 это дает вам (-1 - abs(-1) % 2)/2 == (-1 - 1)/2 = -2/2 = -1 .

Это то же самое на всех языках, которые я знаю – побитовый арифметический сдвиг вправо для -1 будет равным -1, и, как упоминалось выше, эту операцию можно применять только к целым числам.

-1 представляется в двоичном виде, поскольку все биты, заполненные значением 1. Для арифметического сдвига вправо биты будут сдвинуты вправо, а старший бит (слева) будет заполнен знаком значения, для отрицательных значений он будет 1, а для положительного – 0. Таким образом, после сдвига он снова становится -1.

Существуют и другие виды поразрядных сдвигов, а для логического сдвига вправо старший бит заполняется нулем. Вы можете получить дополнительную информацию здесь: http://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift