|
Побитовые операторыПобитовые операторы позволяют считывать и устанавливать конкретные биты целых чисел.
Побитовый сдвиг в PHP - это арифметическая операция. Биты, сдвинутые за границы числа, отбрасываются. Сдвиг влево дополняет число нулями справа, сдвигая в то же время знаковый бит числа влево, что означает что знак операнда не сохраняется. Сдвиг вправо сохраняет копию сдвинутого знакового бита слева, что означает что знак операнда сохраняется. Используйте скобки для обеспечения необходимого. приоритета операторов. Например, $a & $b == true сначала проверяет на равенство, а потом выполняет побитовое и; тогда как ($a & $b) == true сначала выполняет побитовое и, а потом выполняет проверку на равенство. Не забывайте о преобразовании типов данных. Если оба, и левый и правый операнды являются строками, побитовый оператор будет работать с ASCII значениями символов этих строк.
Опция настроек PHP error_reporting использует побитовые значения,
обеспечивая реальную демонстрацию гашения значений битов.
Чтобы показать все ошибки кроме замечаний,
инструкции в файле php.ini предлагают использовать:
Начинаем со значения E_ALL: 00000000000000000111011111111111 Затем берем значение E_NOTICE... 00000000000000000000000000001000 ... и инвертируем его с помощью ~: 11111111111111111111111111110111 Наконец, используем побитовое И (&), чтобы установить только те биты, которые установлены в единицу в обоих значениях: 00000000000000000111011111110111
Другой способ достичь этого - использовать ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR, ^),
чтобы получить только те биты, которые установлены в единицу
либо только в одном, либо только в другом значении:
Опция error_reporting также может быть использована для демонстрации
установки битов. Показать только ошибки и обрабатываемые ошибки можно
следующим образом:
Здесь мы комбинируем E_ERROR 00000000000000000000000000000001 и 00000000000000000001000000000000 с помощью оператора ИЛИ (OR, |), чтобы получить биты, установленные хотя бы в одном операнде: 00000000000000000001000000000001
Пример #1 Побитовыми операции И, ИЛИ и ИСКЛЮЧАЮЩЕЕ ИЛИ (AND, OR и XOR) над целыми числами
<?php Результат выполнения данного примера: --------- --------- -- --------- результат значение оп тест --------- --------- -- --------- Побитовое И (AND) ( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101) ( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101) ( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101) ( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101) ( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101) Побитовое (включающее) ИЛИ (OR) ( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101) ( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101) ( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101) (13 = 1101) = ( 8 = 1000) | ( 5 = 0101) Побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) ( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101) ( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101) ( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101) (13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)
Пример #2 Побитовая операция ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) над строками
<?php
Пример #3 Побитовый сдвиг над целыми числами
<?php Результат выполнения данного примера на 32-битных машинах: --- СДВИГ ВПРАВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- Выражение: 2 = 4 >> 1 Десятичный вид: val=4 res=2 Двоичный вид: val=00000000000000000000000000000100 res=00000000000000000000000000000010 ЗАМЕЧАНИЕ: слева была вставлена копия знакового бита Выражение: 1 = 4 >> 2 Десятичный вид: val=4 res=1 Двоичный вид: val=00000000000000000000000000000100 res=00000000000000000000000000000001 Выражение: 0 = 4 >> 3 Десятичный вид: val=4 res=0 Двоичный вид: val=00000000000000000000000000000100 res=00000000000000000000000000000000 ЗАМЕЧАНИЕ: биты были выдвинуты за правый край Выражение: 0 = 4 >> 4 Десятичный вид: val=4 res=0 Двоичный вид: val=00000000000000000000000000000100 res=00000000000000000000000000000000 ЗАМЕЧАНИЕ: то же, что и выше; нельзя сдвинуть дальше 0 --- СДВИГ ВПРАВО НА ОТРИЦАТЕЛЬНЫХ ЦЕЛЫХ ЧИСЛАХ --- Выражение: -2 = -4 >> 1 Десятичный вид: val=-4 res=-2 Двоичный вид: val=11111111111111111111111111111100 res=11111111111111111111111111111110 ЗАМЕЧАНИЕ: слева была вставлена копия знакового бита Выражение: -1 = -4 >> 2 Десятичный вид: val=-4 res=-1 Двоичный вид: val=11111111111111111111111111111100 res=11111111111111111111111111111111 ЗАМЕЧАНИЕ: биты были выдвинуты за правый край Выражение: -1 = -4 >> 3 Десятичный вид: val=-4 res=-1 Двоичный вид: val=11111111111111111111111111111100 res=11111111111111111111111111111111 ЗАМЕЧАНИЕ: то же, что и выше; нельзя сдвинуть дальше -1 --- СДВИГ ВЛЕВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- Выражение: 8 = 4 << 1 Десятичный вид: val=4 res=8 Двоичный вид: val=00000000000000000000000000000100 res=00000000000000000000000000001000 ЗАМЕЧАНИЕ: правый край был дополнен нулями Выражение: 1073741824 = 4 << 28 Десятичный вид: val=4 res=1073741824 Двоичный вид: val=00000000000000000000000000000100 res=01000000000000000000000000000000 Выражение: -2147483648 = 4 << 29 Десятичный вид: val=4 res=-2147483648 Двоичный вид: val=00000000000000000000000000000100 res=10000000000000000000000000000000 ЗАМЕЧАНИЕ: знаковые биты были выдвинуты Выражение: 0 = 4 << 30 Десятичный вид: val=4 res=0 Двоичный вид: val=00000000000000000000000000000100 res=00000000000000000000000000000000 ЗАМЕЧАНИЕ: биты были выдвинуты за левый край --- СДВИГ ВЛЕВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- Выражение: -8 = -4 << 1 Десятичный вид: val=-4 res=-8 Двоичный вид: val=11111111111111111111111111111100 res=11111111111111111111111111111000 ЗАМЕЧАНИЕ: правый край был дополнен нулями Выражение: -2147483648 = -4 << 29 Десятичный вид: val=-4 res=-2147483648 Двоичный вид: val=11111111111111111111111111111100 res=10000000000000000000000000000000 Выражение: 0 = -4 << 30 Десятичный вид: val=-4 res=0 Двоичный вид: val=11111111111111111111111111111100 res=00000000000000000000000000000000 ЗАМЕЧАНИЕ: биты были выдвинуты за левый край, включая знаковый бит Результат выполнения данного примера на 64-битных машинах: --- СДВИГ ВПРАВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- Выражение: 2 = 4 >> 1 Десятичный вид: val=4 res=2 Двоичный вид: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000010 ЗАМЕЧАНИЕ: слева была вставлена копия знакового бита Выражение: 1 = 4 >> 2 Десятичный вид: val=4 res=1 Двоичный вид: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000001 Выражение: 0 = 4 >> 3 Десятичный вид: val=4 res=0 Двоичный вид: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 ЗАМЕЧАНИЕ: биты были выдвинуты за правый край Выражение: 0 = 4 >> 4 Десятичный вид: val=4 res=0 Двоичный вид: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 ЗАМЕЧАНИЕ: то же, что и выше; нельзя сдвинуть дальше 0 --- СДВИГ ВПРАВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- Выражение: -2 = -4 >> 1 Десятичный вид: val=-4 res=-2 Двоичный вид: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111110 ЗАМЕЧАНИЕ: слева была вставлена копия знакового бита Выражение: -1 = -4 >> 2 Десятичный вид: val=-4 res=-1 Двоичный вид: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111111 ЗАМЕЧАНИЕ: биты были выдвинуты за правый край Выражение: -1 = -4 >> 3 Десятичный вид: val=-4 res=-1 Двоичный вид: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111111 ЗАМЕЧАНИЕ: то же, что и выше; нельзя сдвинуть дальше -1 --- СДВИГ ВЛЕВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- Выражение: 8 = 4 << 1 Десятичный вид: val=4 res=8 Двоичный вид: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000001000 ЗАМЕЧАНИЕ: правый край был дополнен нулями Выражение: 4611686018427387904 = 4 << 60 Десятичный вид: val=4 res=4611686018427387904 Двоичный вид: val=0000000000000000000000000000000000000000000000000000000000000100 res=0100000000000000000000000000000000000000000000000000000000000000 Выражение: -9223372036854775808 = 4 << 61 Десятичный вид: val=4 res=-9223372036854775808 Двоичный вид: val=0000000000000000000000000000000000000000000000000000000000000100 res=1000000000000000000000000000000000000000000000000000000000000000 ЗАМЕЧАНИЕ: знаковые биты были выдвинуты Выражение: 0 = 4 << 62 Десятичный вид: val=4 res=0 Двоичный вид: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 ЗАМЕЧАНИЕ: биты были выдвинуты за левый край --- СДВИГ ВЛЕВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- Выражение: -8 = -4 << 1 Десятичный вид: val=-4 res=-8 Двоичный вид: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111000 ЗАМЕЧАНИЕ: правый край был дополнен нулями Выражение: -9223372036854775808 = -4 << 61 Десятичный вид: val=-4 res=-9223372036854775808 Двоичный вид: val=1111111111111111111111111111111111111111111111111111111111111100 res=1000000000000000000000000000000000000000000000000000000000000000 Выражение: 0 = -4 << 62 Десятичный вид: val=-4 res=0 Двоичный вид: val=1111111111111111111111111111111111111111111111111111111111111100 res=0000000000000000000000000000000000000000000000000000000000000000 ЗАМЕЧАНИЕ: биты были выдвинуты за левый край, включая знаковый бит Внимание
Не используйте сдвиг вправо более чем на 32 бита на 32-битных системах. Не используйте сдвиг влево для получения чисел, требующих для записи более 32 бит. Используйте функции из расширения gmp для побитовых операций над числами, большими чем PHP_INT_MAX. Смотрите также pack(), unpack(), gmp_and(), gmp_or(), gmp_xor(), gmp_testbit(), gmp_clrbit() |
||||||||||||||||||||||