Содержание

PHP побитовые операторы

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

В наличии PHP есть 6 побитовых операторов:

Побитовое И (&)

Оператор & выполняет операцию логическое И над каждым битом своих операндов. Бит результата устанавливается, если соответствующий бит установлен в обоих операндах.

Пример работы оператора «Побитовое И»:

Тоже самое только на примере PHP:


<?php

  $x = 3;         // ...0011
  $y = 5;         // ...0101

  echo $x & $y;   // ...0001 (1)

?>

Побитовое ИЛИ (|)

Оператор | выполняет операцию логическое ИЛИ над каждым битом своих операндов. $y; // …0110 (6) ?>

Побитовое НЕ (~)

Оператор ~ (побитовое НЕ) представляет собой унарный оператор, указываемый перед своим единственным операндом. Он выполняет инверсию всех битов операнда. Из-за способа представления целых со знаком в PHP применение оператора ~ к значению эквивалентно изменению его знака и вычитанию 1.

Пример работы оператора «Побитовое НЕ»:

Тоже самое только на примере PHP:


<?php

  $y = 5;     // ...0101

  echo ~$y;   // ...1010 (-6)

?>

Осталось рассмотреть два оператора — сдвиг влево и сдвиг вправо. Эти операторы можно использовать для быстрого умножения и деления (каждая позиция подразумевает «умножение/деление на 2»).

Сдвиг влево (<<)

Оператор << сдвигает все биты в первом операнде влево на количество позиций, указанное во втором операнде, который должен быть целым числом. Сдвиг значения влево на одну позицию эквивалентен умножению на 2, на две позиции — умножению на 4 и т.д.

Пример работы оператора «Сдвиг влево»:


<?php

  $y = 5;         // 000000101

  // тоже самое что и 5 * 4
  echo $y << 2;   // 000010100 (20)

?>

Сдвиг вправо (>>)

Оператор >> сдвигает все биты в первом операнде вправо на количество позиций, указанное во втором операнде, который должен быть целым числом. Сдвиг значения вправо на одну позицию эквивалентен делению на 2, на две позиции — делению на 4 и т.д.

Пример работы оператора «Сдвиг вправо»:


<?php

  $y = 20;         // 000010100

  // тоже самое что и 20 / 4
  echo $y >> 2;   // 000000101 (5)

?>

Помимо описанных операторов, в PHP также предусмотрены и сокращенные формы записи побитовых операторов.

Сокращенная запись побитовых операторов
Оператор Описание Пример Сокращенная форма записи
&= Присваивает левому операнду результат работы Побитового И $x = $x & $y $x &= $y
|= Присваивает левому операнду результат работы Побитового ИЛИ $x = $x | $y $x |= $y
^= Присваивает левому операнду результат работы Исключающего ИЛИ $x = $x ^ $y $x ^= $y
>>= Присваивает левому операнду результат работы оператора Сдвига вправо $x = $x >> 6 $x >>= 6
<<= Присваивает левому операнду результат работы оператора Сдвига влево $x = $x << 6 $x <<= 6

С этой темой смотрят:

PHP: Побитовые операторы | PHP

Битовые операторы позволяют работать с поразрядным представлением аргументов. $yЗадаются биты, которые установлены в $x или в $y, но не в обоих сразу.~Not~$xБиты, которые установлены в $x, не задаются. И наоборот.<<Shift left$x << $yСмещение битов $x на $y шагов влево.#>>Shift right$x >> $yСмещение битов $x на $y шагов вправо.*

# Каждый шаг означает «умножить на два».
* Каждый шаг означает «поделить на два».

В PHP битовых операциях бит (двоичный разряд) — это базовая единица информации, хранящаяся в вычислительной системе, которая существует в двух возможных состояниях, представленных как ON или OFF. В компьютерной системе состояние ON рассматривается как состояние 1, а OFF — 0. Эти состояния можно сравнить с двумя состояниями электрического переключателя (ВКЛ и ВЫКЛ) и т.п.

Значения задаются в двоичной системе исчисления. В десятичной системе построение числа основано на 10. Давайте посмотрим, как можно построить десятичное число —

231 = (2 ; 102 ) + (3 ; 101) + (1 ; 100)
= 200 + 30 + 1
= 231

Система двоичных чисел следует той же концепции. Единственное отличие состоит в том, что база равна 2, а не 10. Посмотрим, как двоичное число преобразовать в десятичное —

1011010=(1 x 26)+(0 x 25)+(1 x 24)+(1 x 23)+(0 x 22)+(1 x 21)+(0 x 20)
=(1 x 64) +(0 x 32)+(1 x 16)+(1 x 8)+(0 x 4)+(1 x 2)+(0 x 1)
=64+0+16+8+0+2+0
=90

Таким образом, (1011010)2= (90)10

Байт состоит из последовательности битов. Байт состоит из восьми битов. Максимальное значение байта составляет 255. Таким образом устанавливается значение места каждого бита.

1 байт (8 бит)
8-ой7-ой6-ой5-ый4-ый3-ий2-ой1-ый
Установленное значение1286432168421

Табличное представление байта, демонстрирующее, как максимальное значение байта в битовой операции с числами составляет 255:

1 байт (8 бит)
Установленное значение1286432168421
11111111
2726252423222120
1286432168421=255

Десятичное число 93 может быть представлено в двоичной форме:

1 байт (8 бит)
Установленное значение1286432168421
01011101
2726252423222120
0640168401=93
<?php  
$x=13;  
$y=22;  
echo $x & $y;  
?>

Результат примера:

4

Пояснение

Опираясь на приведенные выше таблицы битовых операций, можно сказать, что единственный общий бит находится на третьей позиции с установленным значением 4. Таким образом, $x & $y = 4:

1 байт (8 бит)
Установленное значение1286432168421
$x00001101=13
$y
00010110=22

В приведенной выше таблице для $x (13) установлено значение на первой, третьей и четвертой позиции. Значения позиции равны 1, 4 и 8. А для $y (22) значение установлено на второй, третьей и пятой позициях с соответствующими значениями: 2, 4 и 16.

Единственный бит, который является общим для $x и $y — это третий. Поэтому возвращается 4.

Рассмотрим другой пример оператора &, в котором больше бит.

<?php  
$x=77;  
$y=198;  
echo $x & $y;  
?>

Результат примера PHP битовой операции:

68

Пояснение

1 байт (8 бит)
Place Value1286432168421
$x0
1
001101=77
$y11000110=198

В приведенной выше таблице значение установлено для $x (77) на первой, третьей, четвертой и седьмой позиции. Значения позиций равны 1, 4, 8 и 64. Значение для $y (198) установлено на второй, третьей, седьмой и восьмой позициях с соответствующими значениями: 2, 4, 64 и 128.

Из приведенной выше таблицы видно, что общие для $x и $y — это третий и седьмой биты. Таким образом, возвращается 64 + 4 = 68.

Пример побитового оператора PHP OR:

<?php  
$x=5;  
$y=11;  
echo $x | $y;  
?>

Результат примера:

15

Пояснение

1 байт (8 бит)
Place Value1286432168
4
21
$x00000101=5
$y00001011=11

В приведенной выше таблице битовой операции с числами для $x (5) значение установлено на первой и третьей позициях. Значения позиций соответственно равны 1 и 4. Для $y (11) значения установлены на первой, второй и четвертой позициях с соответствующим значением: 1, 2 и 8.

Для $x и $y общими являются первый, второй, третий или четвертый бит. Возвращаемое значение представляет собой добавление значений позиций битов, то есть: 8 + 4 + 2 + 1 = 15.

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

В приведенной ниже таблице показано, как выполняется операция XOR:

Выражение 1Выражение 2Результат
FalseFalseFalse
FalseTrueTrue
TrueFalseTrue
TrueTrueFalse

В приведенной ниже таблице показано побитовое сравнение оператора XOR:

Бит в Выражении 1Бит в Выражении 2Результат
000
011
101
1
<?php  
$x=12;  
$y=11;  
echo $x ^ $y;  
?>

Результат примера PHP битовой операции:

7

Пояснение

1 байт (8 бит)
Значение позиции1286432168421
$x00001100=12
$y00001011=11

В приведенной выше таблице для $x (12) установлено значение на третьей и четвертой позиции. Значения позиции равны 4 и 8. А для $y (11) значение задано на первой, второй и четвертой позиции с соответствующими значениями: 1, 2 и 8.

$ x и $ y устанавливают вместе первый, второй, третий или четвертый бит. Но вместе они используют только 4-й бит. Поэтому возвращаемое значение представляет собой добавление места для них. Но не совместно используемый бит: 4 + 2 + 1 = 7.

В приведенной ниже таблице будет показано, как оператор NOT выполняет операции с $x и $y и возвращает true, когда заданный в одном выражении бит не задан в другом выражении.

<?php  
$x=12;  
$y=10;  
echo $x & ~ $y;  
?>

Результат примера:

4

Пояснение

1 байт (8 бит)
Значение позиции1286432168421
$x00001100=12
$y00001010=10

В приведенной выше таблице для $x (12) значение установлено на третьей и четвертой позициях. Значения позиции равны 4 и 8. Для $y (10) значение установлено на второй и четвертой позициях с соответствующими значениями 2 и 8.

Для $x и $y заданы биты на первой, второй, третьей и четвертой позициям, но общий для них только четвертый бит. Возвращаемое значение равно 4, так как это единственное значение, заданное для $x, но не заданное для $y.

<?php  
$x=12;  
$y=10;  
echo ~ $x &  $y;  
?>

Результат примера:

2

Пояснение

В этом случае возвращаемое значение равно 2, потому что бит установлен для $y, но не установлен для $x.

Если a и b — это два числа. Оператор сдвига перемещает бит b на определенное количество позиций. Каждый шаг означает умножение на два (сдвиг влево). Если это сдвиг вправо, тогда каждый шаг означает деление на два.

<?php  
$x=8;  
$y=3;  
echo $x << $y;  
?>

Результат примера битовой операции

64

Пояснение

1 байт (8 бит)
Значение позиции1286432168421
$x00001000=8
Результат01000000=64

В приведенном выше примере берется значение $x, которое равно 8, и выполняется операция сдвига влево: 8 умножается на 2 три раза. Таким образом, мы получаем 8 x 2 x 2 x 2 = 64.

<?php  
$x=12;  
$y=4;  
echo  $x << $y;  
?>

Результат примера:

192

Пояснение

В приведенном выше примере берется значение $x, равное 12, и выполняется операция сдвига влево: умножается на 2 четыре раза. Таким образом, мы получаем 12 x 2 x 2 x 2 x 2 = 192.

1 байт (8 бит)
Значение позиции1286432168421
$x00001100=12
Результат11000000=192
<?php  
$x=8;  
$y=3;  
echo $x >> $y;  
?>

Результат примера битовой операции с числами:

1

Пояснение

1 байт (8 бит)
Значение позиции1286432168421
$x00001000=8
Результат00000001=1

В приведенном выше примере берется значение $x, которое равно 8, и выполняется операция сдвига вправо: 8 делится на 2 три раза. Таким образом, получаем 8/2 = 4/2 = 2/2 = 1.

<?php  
$x=96;  
$y=5;  
echo  $x >> $y;  
?>

Результат примера:

3

Пояснение

1 байт (8 бит)
Значение позиции1286432168421
$x01100000=96
Результат00000011=3

В приведенном выше примере берется значение $x, равное 96, и выполняется операция сдвига вправо: 96 делится на 2 пять раз. Таким образом, мы получаем 96/2 = 48/2 = 24/2 = 12/2 = 6/2 = 3.

<?php  
$x=64;  
$y=7;  
echo  $x >> $y;   
?>

Результат примера PHP битовой операции:

0

Пояснение

1 байт (8 бит)
Значение позиции1286432168421
$x01000000=64
Результат00000000=0

В приведенном выше примере берется значение $x, равное 64, и выполняется операция сдвига вправо: 64 делится на 2 семь раз. При делении в определенный момент нам нечего делить. Таким образом, результат равен 0.

Дайте знать, что вы думаете по этой теме в комментариях. За комментарии, лайки, отклики, дизлайки, подписки низкий вам поклон!

Данная публикация является переводом статьи «PHP Bitwise operator» , подготовленная редакцией проекта.

Побитовые операторы в PHP

Что такое побитовые операторы?

Побитовые операторы — арифметическая операция, которая отвечает за побитовый сдвиг в PHP.

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

Для чего нужны побитовые операторы?

Побитовые операторы в PHP позволяют считывать и устанавливать конкретные биты целых чисел.

Синтаксис побитовых операторов

Синтаксис всех побитовых операторов представлен в таблице ниже. XOR Устанавливает каждый бит в 1, если только один из двух битов равен 1 ~ NOT Инвертирует все биты << Сдвиг влево с нулевым заполнением Сдвигает влево, вставляя нули справа и позволяя крайним левым битам упасть >> Подпись вправо Сдвигает вправо, вставляя копии крайнего левого бита слева и позволяя крайним правым битам отпасть >>> Сдвиг вправо с нулевым заполнением Сдвигает вправо, вставляя нули слева, и позволяет крайним правым битам отпасть

Примеры

Операция Результат Такой же, как Результат
5 & 1 1 0101 & 0001  0001
5 | 1 5 0101 | 0001  0101
~ 5 10  ~0101  1010
5 << 1 10 0101 << 1  1010
5 ^ 1 4 0101 ^ 0001  0100
5 >> 1 2 0101 >> 1  0010
5 >>> 1 2 0101 >>> 1  0010

JavaScript использует 32-битные побитовые операнды

JavaScript хранит числа как 64-битные числа с плавающей запятой, но все побитовые операции выполняются с 32-битными двоичными числами.

Перед выполнением побитовой операции JavaScript преобразует числа в 32-битные целые числа со знаком.

После выполнения побитовой операции результат конвертируется обратно в 64-битные числа JavaScript.

В приведенных выше примерах используются 4-битные двоичные числа без знака. Из-за этого ~ 5 возвращает 10.

Поскольку JavaScript использует 32-битные целые числа со знаком, он не вернет 10. Он вернет -6.

00000000000000000000000000000101 (5)

11111111111111111111111111111010 (~5 = -6)

Целое число со знаком использует крайний левый бит как знак минус.



Побитовое AND JavaScript

Когда побитовое AND выполняется для пары битов, он возвращает 1, если оба бита равны 1.

Один битный пример:
ОперацияРезультат
0 & 00
0 & 10
1 & 00
1 & 11
4 битный пример:
ОперацияРезультат
1111 & 00000000
1111 & 00010001
1111 & 00100010
1111 & 01000100

Побитовое OR

Когда для пары битов выполняется побитовое OR, оно возвращает 1, если один из битов равен 1:

Один битный пример:
ОперацияРезультат
0 | 00
0 | 1
1 | 01
1 | 11
4 битный пример:
ОперацияРезультат
1111 | 00001111
1111 | 00011111
1111 | 00101111
1111 | 01001111

Побитовое XOR JavaScript

Когда побитовое XOR выполняется для пары битов, он возвращает 1, если биты различны:

Один битный пример:
ОперацияРезультат
0 ^ 00
0 ^ 1
1 ^ 01
1 ^ 1
4 битный пример:
ОперацияРезультат
1111 ^ 00001111
1111 ^ 00011110
1111 ^ 00101101
1111 ^ 01001011

Поразрядное AND (&) JavaScript

Побитовое AND возвращает 1, только если оба бита равны 1:

ДесятичныйДвоичный
500000000000000000000000000000101
100000000000000000000000000000001
5 & 100000000000000000000000000000001 (1)

Побитовое OR (|) JavaScript

Побитовое OR возвращает 1, если один из битов равен 1:

ДесятичныйДвоичный
500000000000000000000000000000101
100000000000000000000000000000001
5 | 100000000000000000000000000000101 (5)

Побитовое XOR (^) JavaScript

Побитовое XOR возвращает 1, если биты разные:

ДесятичныйДвоичный
500000000000000000000000000000101
100000000000000000000000000000001
5 ^ 100000000000000000000000000000100 (4)

Побитовое NOT (~) JavaScript

ДесятичныйДвоичный
500000000000000000000000000000101
~511111111111111111111111111111010 (-6)

JavaScript (нулевое заполнение) Побитовый сдвиг влево (<<)

Это сдвиг влево с нулевым заполнением. Один или несколько нулевых бит вставляются справа, а крайние левые биты отпадают:

ДесятичныйДвоичный
500000000000000000000000000000101
5 << 100000000000000000000000000001010 (10)

JavaScript (сохранение знака) Побитовый сдвиг вправо (>>)

Это знак, сохраняющий правый сдвиг. Копии крайнего левого бита вставляются слева, а крайние правые биты отваливаются:

ДесятичныйДвоичный
-511111111111111111111111111111011
-5 >> 111111111111111111111111111111101 (-3)

JavaScript (нулевое заполнение) сдвиг вправо (>>>)

Это сдвиг вправо с нулевым заполнением. Один или несколько нулевых битов вставляются слева, а крайние правые биты отваливаются:

ДесятичныйДвоичный
500000000000000000000000000000101
5 >>> 100000000000000000000000000000010 (2)

Двоичные числа

Двоичные числа с одним набором битов легко понять:

Двоичное представлениеДесятичное значение
000000000000000000000000000000011
000000000000000000000000000000102
000000000000000000000000000001004
000000000000000000000000000010008
0000000000000000000000000001000016
0000000000000000000000000010000032
0000000000000000000000000100000064

Установка еще нескольких битов показывает двоичный паттерн:

Двоичное представлениеДесятичное значение
000000000000000000000000000001015 (4 + 1)
0000000000000000000000000000110113 (8 + 4 + 1)
0000000000000000000000000010110145 (32 + 8 + 4 + 1)

Двоичные числа JavaScript хранятся в формате дополнения до двух.

Это означает, что отрицательное число является побитовым NOT числа плюс 1:

Двоичное представлениеДесятичное значение
000000000000000000000000000001015
11111111111111111111111111111011-5
000000000000000000000000000001106
11111111111111111111111111111010-6
0000000000000000000000000010100040
11111111111111111111111111011000-40

Преобразование десятичного числа в двоичное


Преобразование двоичного числа в десятичное


php — Понимание оператора PHP & (амперсанд, бит и)

Две операции, которые являются фундаментальными для двоичных систем: OR и ​​AND.

ИЛИ означает «если А включен или В включен». Примером из реальной жизни могут быть два переключателя параллельно. Если любой из них пропускает ток, ток проходит.

И означает «если включены и А, и В». Пример реального мира — два переключателя в серии. Ток будет проходить, только если оба позволяют току.

В компьютере это не физические переключатели, а полупроводники, и их функциональность называется логические элементы . Они выполняют те же действия, что и переключатели, — реагируют на ток или вообще без тока.

При применении к целым числам каждый бит в одном числе объединяется с каждым битом в другом числе. Таким образом, чтобы понять побитовые операторы OR и ​​AND, вам нужно преобразовать числа в двоичные числа, а затем выполнить операцию OR или AND для каждой пары совпадающих битов.

Поэтому:

00011011 (odd number)
AND
00000001 (& 1)
== 
00000001 (results in 1)

В то время как

00011010 (even number)
AND
00000001 (& 1)
==
00000000 (results in 0)

Поэтому операция (& 1) сравнивает самый правый бит с 1, используя логику AND. Все остальные биты фактически игнорируются, потому что ничто и ничто не есть ничто. means XOR.

Другие могут быть составлены путем объединения этих, например:

~ (a & b) is equivalent to a NAND operation

Примечание, специфичное для PHP

Битовые операторы не работают со значениями с плавающей запятой, и в PHP значения с плавающей запятой сначала будут неявно преобразованы в целые числа. Числа вне диапазона, которые могут быть выражены как целые числа, будут обрезаны до нуля, то есть все числа в PHP_INT_MAX будут выглядеть «четными» в выражении ($num & 1)). Если вы хотите поддерживать числа вне PHP_INT_MIN/PHP_INT_MAX, вам понадобится fmod($num, 2). Если, однако, вы используете 64-битную PHP, ваши целые числа будут иметь большую точность, чем числа с плавающей точкой.

a1, a2, …, a2n. Сейчас Ксюша изучает битовые операции. Чтобы лучше понять как они работают, Ксюша решила подсчитать некоторое значение v по a. А именно, значение v считается в несколько итераций. На первой итерации, Ксюша записывает новую последовательность a1 or a2, a3 or a4, …, a2n - 1 or a2n, состоящую из 2n - 1 элементов. Другими словами, она записывает побитовое ИЛИ соседних элементов последовательности a. На второй итерации, Ксюша записывает побитовое исключающее ИЛИ соседних элементов полученной после первой итерации последовательности. На третьей итерации Ксюша записывает побитовое ИЛИ соседних элементов последовательности, полученной после второй итерации. И так далее операции побитовое исключающее ИЛИ и побитовое ИЛИ чередуются. В конце концов получится последовательность, состоящая из одного элемента, этот элемент и равен v. Рассмотрим пример, пусть последовательность a = (1, 2, 3, 4). Тогда запишем все преобразования (1, 2, 3, 4)  →  (1 or 2 = 3, 3 or 4 = 7)  →  (3 xor 7 = 4), в итоге v = 4. Вам задана изначальная последовательность Ксюши. Но посчитать значение v по заданной последовательности было бы слишком просто, поэтому Вам дополнительно заданы m запросов. Каждый запрос — это пара целых чисел p, b. Запрос p, b означает, что нужно выполнить присвоение ap = b. После каждого запроса, нужно вывести новое значение v посчитанное по новой последовательности a.

У начинающего программиста Ксюши есть последовательность a, состоящая из 2n неотрицательных целых чисел: a1, a2, …, a2n. Сейчас Ксюша изучает битовые операции. Чтобы лучше понять как они работают, Ксюша решила подсчитать некоторое значение v по a.

А именно, значение v считается в несколько итераций. На первой итерации, Ксюша записывает новую последовательность a1 or a2, a3 or a4, …, a2n - 1 or a2n, состоящую из 2n - 1 элементов. Другими словами, она записывает побитовое ИЛИ соседних элементов последовательности a. На второй итерации, Ксюша записывает побитовое исключающее ИЛИ соседних элементов полученной после первой итерации последовательности. На третьей итерации Ксюша записывает побитовое ИЛИ соседних элементов последовательности, полученной после второй итерации. И так далее операции побитовое исключающее ИЛИ и побитовое ИЛИ чередуются. В конце концов получится последовательность, состоящая из одного элемента, этот элемент и равен v.

Рассмотрим пример, пусть последовательность a = (1, 2, 3, 4). Тогда запишем все преобразования (1, 2, 3, 4)  →  (1 or 2 = 3, 3 or 4 = 7)  →  (3 xor 7 = 4), в итоге v = 4.

Вам задана изначальная последовательность Ксюши. Но посчитать значение v по заданной последовательности было бы слишком просто, поэтому Вам дополнительно заданы m запросов. Каждый запрос — это пара целых чисел p, b. Запрос p, b означает, что нужно выполнить присвоение ap = b. После каждого запроса, нужно вывести новое значение v посчитанное по новой последовательности a.

Побитовые логические операции


 Побитовые логические операции — это &, |, А и ~. Результаты выполнения каждой из этих операций приведены в табл. 4.3. В ходе,ознакомления с последующим материалом помните, что побитовые операции применяются к каждому отдельному биту каждого операнда. Таблица 4.3. Результаты выполнения побитовых логических операций
A B A|B A&B A^B ~A
0 0 0 0 0 1
1 0 1 0 1 0
0 1 1 0 1 1
1 1 1 1 0 0

Побитовое NOT

Называемая также операцией побитового дополнения, унарная операция NOT (НЕ), ~, инвертирует все биты операнда. Например, число 42, которое имеет следующую последовательность битов:

00101010

в результате применения операции NOT преобразуется в:

11010101

Побитовое AND

Значение бита, полученное в результате побитовой операции AND, &, равно 1, если соответствующие биты в операндах также равны 1. Во всех остальных случаях значение результирующего бита равно 0. Например:

  00101010 42
& 00001111 15
-------------
  00001010 10

Побитовое OR

Результирующий бит, полученный в результате выполнения операции OR, |, равен 1, если соответствующий бит в любом из операторов равен 1, как показано в следующем примере:

  00101010 42
| 00001111 15
-------------
  00101111 47

Побитовое XOR

Результирующий бит, полученный в результате выполнения операции XOR, А, равен 1, если соответствующий бит только в одном из операндов равен 1. 00001111 15
————-
  00100101 37

PHP Побитовые операторы — w3resource

Описание

Побитовые операторы позволяют работать с поразрядным представлением своих аргументов.

долл. США долл. США долл. США долл. США
Оператор Имя Пример Результат
и и долл. США x и Устанавливаются биты, которые установлены как в $ x, так и в $ y.
| или $ x | Устанавливаются биты, которые установлены либо в $ x, либо в $ y. Биты, которые установлены в $ x или $ y, но не оба установлены.
~ Не ~ Биты, установленные в $ x, не устанавливаются, и наоборот.
<< Сдвиг влево $ x << $ y Сдвинуть биты $ x $ y шагов влево. #
>> Сдвиг вправо $ x >> $ y Сдвиньте биты $ x $ y шагов вправо.*

# Каждый шаг означает «умножить на два»
* Каждый шаг означает «разделить на два»

Что такое бит?

Бит ( B inary dig IT ) — это основная единица информации, хранящаяся в вычислительной системе, которая существует в двух возможных состояниях, представленных как ON или OFF . В компьютерной системе состояние ON рассматривается как 1 , а состояние OFF рассматривается как 0 .Эти состояния можно сравнить с двумя состояниями триггера, двумя состояниями электрического переключателя ( ВКЛ, и ВЫКЛ, ) и т. Д. Эти два значения 0 и 1 называются двоичной цифрой, и эти цифры находятся в определенной системе счисления, то есть в ДВОИЧНОЙ системе счисления, которая строится на основе 2.

В десятичной системе счисления число строится на основе 10. Давайте посмотрим, как можно построить десятичное число —

231 = (2 x 10 2 ) + (3 x 10 1 ) + (1 x 10 0 )
= 200 + 30 + 1
= 231

Двоичная система счисления также следует той же концепции.Единственная разница в том, что основание 2 вместо 10. Давайте посмотрим, как двоичное число можно преобразовать в десятичное —

.

1011010 = (1 x 2 6 ) + (0 x 2 5 ) + (1 x 2 4 ) + (1 x 2 3 ) + (0 x 2 2 ) + (1 x 2 1 ) + (0 x 2 0 )
= (1 x 64) + (0 x 32) + (1 x 16) + (1 x 8) + (0 x 4) + (1 x 2) + (0 х 1)
= 64 + 0 + 16 + 8 + 0 + 2 + 0
= 90

Итак, (1011010) 2 = (90) 10

Байт

Байт состоит из последовательности битов.Байт состоит из восьми бит. Максимальное значение байта — 255, поэтому устанавливается значение разряда каждого бита.

Табличное представление байта

1 байт (8 бит)
8-я 7-я 6-я 5-я 4-я 3-й 2-я 1-й
Разрядная стоимость 128 64 32 16 8 4 2 1

Вот табличное представление байта показывает, как максимальное значение байта равно 255

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
1 1 1 1 1 1 1 1
2 7 2 6 2 5 2 4 2 3 2 2 2 1 2 0
128 64 32 16 8 4 2 1 = 255

Десятичное число 93 может быть представлено в двоичной форме, как показано ниже —

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
0 1 0 1 1 1 0 1
2 7 2 6 2 5 2 4 2 3 2 2 2 1 2 0
0 64 0 16 8 4 0 1 = 93

Побитовое И

Пример PHP поразрядного И с одним общим битом

    

Вывод примера

 4 

Пояснение

Итак, ссылаясь на наши таблицы выше, можно сказать, что единственный бит этих двух долей находится на 3-й позиции при значении 4.Итак, $ x & $ y = 4.

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 0 0 0 1 1 0 1 = 13
$ и 0 0 0 1 0 1 1 0 = 22

В приведенной выше таблице значение, установленное для $ x (13) на 1-м, 3-м и 4-м месте.Значения разряда соответственно 1,4 и 8 и значение, установленное для $ y (22) на 2-м, 3-м и 5-м месте с соответствующими значениями 2, 4 и 16.

Итак, из вышеприведенной таблицы видно, что единственный бит, который используются совместно $ x и $ y, — это третий бит. Итак, 4 возвращается

Посмотреть пример побитового И в php с одним общим битом в браузере

Давайте посмотрим на другой пример оператора &, который разделяет больше бит —

Пример PHP поразрядного И с двумя общими битами

    

Вывод примера

 68 

Пояснение

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 1 0 0 1 1 0 1 = 77
$ и 1 1 0 0 0 1 1 0 = 198

В приведенной выше таблице значение $ x (77) установлено на 1-м, 3-м, 4-м и 7-м местах.Значения разряда: 1, 4, 8 и 64, а значение, установленное для $ y (198) на 2-м, 3-м, 7-м и 8-м месте с соответствующими значениями разряда 2, 4, 64 и 128.

Итак, из вышеприведенной таблицы видно, что биты, которые совместно используются $ x и $ y, являются 3-м и 7-м битами. Таким образом, возвращается 64 + 4 = 68.

Посмотреть пример побитового И для php с двумя общими битами в браузере

Побитовое ИЛИ

Пример побитового ИЛИ PHP

    

Вывод примера

 15 

Пояснение

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 0 0 0 0 1 0 1 = 5
$ и 0 0 0 0 1 0 1 1 = 11

В приведенной выше таблице значение $ x (5) установлено на 1-м и 3-м месте.Значения разряда соответственно равны 1 и 4, а значение, установленное для $ y (11) на 1-м, 2-м и 4-м месте с соответствующими значениями разряда 1, 2 и 8.

Итак, из вышеприведенной таблицы видно, что $ x и $ y устанавливают вместе 1-й, 2-й, 3-й или 4-й бит. Таким образом, возвращаемое значение — это сложение разряда битов набора, то есть 8 + 4 + 2 + 1 = 15.

Посмотреть пример побитового ИЛИ php в браузере

Побитовое исключающее ИЛИ

Оператор Xor также выполняет побитовое сравнение в двух числовых выражениях и устанавливает соответствующий бит в результате.Когда одно и только одно выражение оценивается как истинное, результат будет истинным.

В таблице ниже показано, как выполняется операция XOR.

Выражение1 Выражение2 Результат
Ложь Ложь Ложь
Ложь Истинно Истинно
Истинно Ложь Истинно
Истинно Истинно Ложь

В приведенной ниже таблице показано побитовое сравнение побитового XOR —

. $ y; ?>

Вывод примера

 7 

Пояснение

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 0 0 0 1 1 0 0 = 12
$ и 0 0 0 0 1 0 1 1 = 11

В приведенной выше таблице значение $ x (12) установлено на 3-м и 4-м месте.Значения разряда соответственно 4 и 8, и значение устанавливается для $ y (11) на 1-м, 2-м и 4-м месте с соответствующими значениями 1, 2 и 8.

Итак, вы можете видеть из приведенной выше таблицы, что $ x и $ y устанавливают вместе либо 1-й, либо 2-й, либо 3-й или 4-й бит, но совместно используют только 4-й бит. Таким образом, возвращаемое значение — это добавление разряда установленных битов, но не совместно используемых битов, то есть 4 + 2 + 1 = 7.

Посмотреть пример побитового XOR на php в браузере

Побитовое НЕ

В таблице ниже показано, как оператор NOT работает с $ x и $ y и возвращает истину, если установленный бит одного выражения не установлен в другом выражении.

Пример побитового НЕ использования PHP после AND

    

Вывод примера

 4 

Пояснение

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 0 0 0 1 1 0 0 = 12
$ и 0 0 0 0 1 0 1 0 = 10

В приведенной выше таблице значение $ x (12) установлено на 3-м и 4-м месте.Значения разряда соответственно 4 и 8, а значение устанавливает для $ y (10) на 2-м и 4-м месте с соответствующими значениями 2 и 8.

Итак, вы можете видеть из приведенной выше таблицы, что $ x и $ y устанавливают вместе либо 1-й, либо 2-й, либо 3-й или 4-й бит, но совместно используют только 4-й бит. Итак, возвращаемое значение — 4, потому что биты установлены только в $ x, но не в $ y.

Посмотреть пример побитового использования php НЕ после И в браузере

Пример побитового НЕ использования PHP до И

    

Вывод примера

 2 

Пояснение

В этом случае возвращаемое значение равно 2, потому что бит установлен на $ y, но не на $ x.

Посмотреть пример побитового НЕ с использованием php перед И в браузере

Сдвиг бит

Если a и b — два числа, BIT SHIFTING сдвигает биты b на количество шагов. каждый шаг относится к умножению на два, если это BIT SHIFT LEFT. Если это BIT SHIFT RIGHT, то каждый шаг относится к делению на два.

Пример сдвига битов PHP (сдвиг влево)

    

Вывод примера

 64 

Пояснение

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 0 0 0 1 0 0 0 = 8
Выход 0 1 0 0 0 0 0 0 = 64

В приведенном выше примере берется значение $ x, равное 8, и выполняется операция BIT SHIFT LEFT.Итак, 8 умножается на 2 трижды. Таким образом, мы получаем 8 x 2 x 2 x 2 = 64.

Посмотреть пример сдвига битов php (сдвиг влево) в браузере

Расширенный пример сдвига битов PHP (сдвиг влево)

    

Вывод примера

 192 

Пояснение

В приведенном выше примере берется значение $ x, равное 12, и выполняется операция BIT SHIFT LEFT.Итак, 12 умножается на 2 в четыре раза. Таким образом, получаем 12 x 2 x 2 x 2 x 2 = 192.

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 0 0 0 1 1 0 0 = 12
Выход 1 1 0 0 0 0 0 0 = 192

Просмотрите предварительный пример сдвига битов php (сдвиг влево) в браузере

Пример сдвига битов PHP (сдвиг вправо)

  > $ y;
?>  

Вывод примера

 1 

Пояснение

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 0 0 0 1 0 0 0 = 8
Выход 0 0 0 0 0 0 0 1 = 1

В приведенном выше примере берется значение $ x, равное 8, и выполняется операция BIT SHIFT RIGHT.Итак, 8 делится на 2 трижды. Таким образом, получаем 8/2 = 4/2 = 2/2 = 1.

Посмотреть пример сдвига битов php (сдвиг вправо) в браузере

Расширенный пример сдвига битов PHP (сдвиг вправо)

  > $ y;
?>  

Вывод примера

3

Пояснение

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 1 1 0 0 0 0 0 = 96
Выход 0 0 0 0 0 0 1 1 = 3

В приведенном выше примере берется значение $ x, равное 96, и выполняется операция BIT SHIFT RIGHT.Итак, 96 делится на 2 пять раз. Таким образом, мы получаем 96/2 = 48/2 = 24/2 = 12/2 = 6/2 = 3.

Просмотрите предварительный пример сдвига битов php (сдвиг вправо) в браузере

Пример PHP Bit Shift (сдвиг вправо) превышает значение шага

  > $ y;
?>
  

Вывод примера

 0 

Пояснение

1 байт (8 бит)
Значение места 128 64 32 16 8 4 2 1
$ x 0 1 0 0 0 0 0 0 = 64
Выход 0 0 0 0 0 0 0 0 = 0

В приведенном выше примере берется значение $ x, равное 64, и выполняется операция BIT SHIFT RIGHT.Итак, 64 делится на 2 семь раз. При делении в определенный момент нам нечего делить. Таким образом, возврат равен 0.

Посмотреть предварительный пример php Bit Shifting (сдвиг вправо) превышает значение шага в браузере

Предыдущая: Операторы присваивания
Следующая: Строковые операторы

Актуальны ли побитовые операторы в современном PHP?

Многие из вас, вероятно, почесали голову, читая это название. «Что за бит?»

В этой статье мы рассмотрим, что такое побитовые операторы и актуально ли их использование в современную эпоху вычислений.

Пример использования

Здесь перечислены

побитовых операторов, но, чтобы наглядно продемонстрировать пример, мы остановимся только на одном: поразрядных и ( и ). Пример заставил меня щелкнуть. Вот что мы сделаем — погрузимся прямо в пример.

Представьте, что у вас есть веб-сайт, на котором данный пользователь может иметь определенные разрешения. Например, такой журнал, как SitePoint:

  • Автор может черновики CRUD, а также редактировать свой профиль.
  • редактор может, в дополнение к вышесказанному, черновики и готовые сообщения CRUD, а также профили авторов CRUD.
  • администратор может, в дополнение к вышеупомянутому, добавить права администратора.

Поскольку у пользователя может быть несколько разрешений, существует несколько способов определения разрешений в базе данных и системе, использующей ее.

Двойное соединение

Добавьте роли, добавьте разрешения, прикрепите разрешения к ролям в таблице соединения, затем создайте другую таблицу соединения и привяжите некоторые роли к некоторым пользователям.

Этот подход создает четыре дополнительных таблицы:

  • разрешений
  • ролей
  • разрешений <-> роли
  • ролей <-> пользователей

Немного накладных расходов. Представьте, что вам нужно регулярно редактировать их или перечислять в приложении в некоторых часто посещаемых списках. Только тяжелое кеширование спасет это приложение от разрушения при большой нагрузке.

Тем не менее, одним из преимуществ является то, что, действительно хорошо определяя роли с помощью сложных разрешений, вам нужно только закрепить пользователей за ролями, и у вас все хорошо — это позволяет быстро и легко объединить стол.

Одиночное объединение

Добавить разрешения, добавить таблицу соединений, прикрепить некоторые разрешения для некоторых пользователей

Этот подход создает две дополнительные таблицы:

  • разрешений
  • разрешений <-> пользователей

Намного меньше накладных расходов, чем в предыдущем примере, но у вас гораздо больше записей в объединенной таблице, потому что у пользователя может быть МНОГО разрешений (только CRUD для черчения — это 4 разрешения). При большом количестве пользователей и большом количестве разрешений эта таблица может быстро стать тяжелой.

Паническое бегство за колонной

Добавьте столбец в таблицу пользователей для каждого разрешения, затем сделайте его тип данных tinyint (1) (в основном логическим), чтобы проверить разрешение как «включено» или «выключено».

Настройка разрешений для пользователя будет выглядеть примерно так:

  ОБНОВЛЕНИЕ `users` SET` editProfile` = 1, `deleteProfile` = 0,` createDraft` = 1, `publishDraft` = 0 ... ГДЕ` id` = 5
  

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

Однако, поскольку список столбцов, если смотреть издалека, напоминает двоичное число (1010), этот подход является отличным переходом в другой…

Побитовый подход

Прежде чем мы углубимся в этот подход, давайте пройдем ускоренный курс по двоичной системе.

Двоичные числа

Все компьютеры хранят данные в двоичном формате: 0 или 1.Итак, число 14 на самом деле хранится как: 1110. Как так?

Двоичные числа вычисляются справа налево при вычислении их значения, как и действительные числа. Итак, число 1337 означает:

  • 1 х 7
  • + 3 х 10
  • + 3 х 100
  • + 1 х 1000

Потому что каждая цифра в десятичной системе счисления (основание 10) умножается на 10. Первая — 1, следующая — 10, следующая после этой 100, следующая 1000 и т. Д.

В двоичной системе основание равно 2, поэтому каждая цифра умножается на 2.Таким образом, число 1110:

.
  • 0 х 1
  • + 1 х 2
  • + 1 х 4
  • + 1 х 8

Это 2 + 4 + 8, что составляет 14.

Да, преобразовать двоичные числа в десятичные так просто.

Итак, когда мы смотрим на наши столбцы разрешений до 1010, это также можно рассматривать как число 10, записанное в двоичной форме. Хм, может, мы тут что-то поняли.

Если у нас есть 1010 в качестве разрешений, это означает, что 2-й и 4-й бит установлены, а первый и третий — нет (потому что они равны 0).2), что равно 4 и т. Д. Таким образом, все это очень легко запомнить.

Так чем это нам поможет?

Побитовый подход

Что ж, посмотрев на разрешения издалека, мы можем представить состояние всех столбцов сразу с помощью одного двоичного числа. Если мы можем представить все столбцы сразу одним двоичным числом, это означает, что мы также можем представить его одним целым числом при переводе в десятичное!

Если бы у нас был единственный столбец разрешений , который содержал значение 14 , мы бы теперь знали, что это на самом деле 1110 , и мы бы знали, что у нас есть три из четырех разрешений! Но какие 3 наши из 4?

Представьте себе следующее отображение разрешений:

РАЗРЕШЕНИЯ НА ИЗМЕНЕНИЕ СОЗДАТЬ ПРОФИЛЬ РЕДАКТИРОВАНИЕ ПРОФИЛЯ УДАЛИТЬ ПРОФИЛЬ ПРОЕКТ СОЗДАТЬ ПРОЕКТ РЕДАКТИРОВАНИЯ УДАЛИТЬ ПРОЕКТ ПУБЛИКАЦИЯ ПРОЕКТА ЗАВЕРШЕННОЕ РЕДАКТИРОВАНИЕ ЗАВЕРШЕНО УДАЛИТЬ
512 256 128 64 32 16 8 4 2 1

Число 14 в двоичном формате — 1110, но количество нулей слева не имеет значения, поэтому мы можем дополнять его, пока не достигнем количества разрешений в таблице: 0000001110.Это по-прежнему 14, что соответствует только разрешениям из таблицы выше. Для всех намерений и целей 0000001110 === 1110.

В соответствии с этим мы видим, что учетная запись с разрешением 14 имеет разрешения: DRAFT_DELETE , DRAFT_PUBLISH и FINISHED_EDIT . Конечно, это не совсем соответствует реальной настройке разрешений, но это просто пример, с помощью которого мы можем экстраполировать, что если бы у кого-то был 1111111111, у него были бы ВСЕ разрешения (вероятно, пользователь-администратор).В десятичном формате это 1023. Итак, кто-то со значением 1023 в столбце разрешений — это кто-то со всеми разрешениями.

Но как мы можем проверить это в нашем коде? Другими словами, как мы можем узнать, установлен ли бит разрешения (1) или нет (0), особенно если число хранится как десятичное, а не двоичное?

Вот для чего нужны побитовые операторы — в частности, одиночный амперсанд и , также известный как побитовые и .

MySQL поддерживает это так:

  SELECT * FROM user WHERE id = 5 AND 512 & permissions
  

Это переводится буквально как «выбрать всех пользователей с ID 5, у которых также 512 бит из столбца разрешений установлен на 1 ″.Вы можете проверить наличие других битов, просто изменив их значение: 256, 128, 64, 32, 16, 8, 4, 2 или 1.


[необязательно] примечание

«Давайте перейдем к техническим вопросам»

Пропустите этот разделенный раздел, если вы не хотите знать, как работает этот оператор или аналогичные операторы, а просто хотите продолжить рассмотрение примера.

Когда мы говорим AND 512 и permissions , мы ищем, чтобы часть после AND была ИСТИНА, потому что именно так работают SQL-запросы — они оценивают условия и возвращают те строки, которые возвращают истину в отношении требований.

Следовательно, значение 512 & permissions должно быть истинным. Мы знаем, что любое ненулевое значение, будь то целое число, логическое значение «истина» или непустая строка, на самом деле считается «истиной». Так что 512 это правда. 1 верно. 0 — ложь. 128 верно. И т. Д.

512 — целое число с основанием 10, а разрешения — столбец, который может содержать целое число с основанием 10. поразрядно и фактически смотрит на сечение этих двух чисел и возвращает биты, которые установлены (1) в обоих из них.Итак, если число 512 равно 1000000000, а значение разрешений — 1023, при преобразовании в двоичный формат это 1111111111. Сечение этих значений возвращает 1000000000, потому что в обоих числах установлен только крайний левый бит. Когда мы преобразуем это обратно в десятичное число, это 512, что считается истинным .

На самом деле это логические, а не арифметические операторы, поскольку они проверяют истинность на основе условия. Если у нас есть числа 1110 и 1010, вот что они дают с учетом различных побитовых операторов:

и | ^ ~
Операнд A 1110 1110 1110 1110
Операнд B 1010 1010 1010 /
Результат 1010 1110 0100 0001
  • и возвращает двоичное число, в котором установлены все биты, установленные в обоих операндах. возвращает двоичное число со всеми установленными битами, установленными в любом из операндов, но не в обоих.
  • ~ просто возвращает противоположное — все те, которые не установлены в исходном операнде, теперь установлены.

Есть также операторы побитового сдвига: сдвиг влево << и сдвиг вправо >> . Они резко изменяют значения двоичных чисел, буквально перемещая все установленные биты на одно место вправо или влево. Их использование в нашем контексте вызывает сомнения, поэтому мы не будем их здесь рассматривать.


А в PHP мы можем проверить, установлен ли бит так:

  if (1023 & 1) {

}
  

Но это действительно очень сложно расшифровать - просто смотреть на необработанные числа непонятно или непонятно. Итак, в PHP лучше использовать константы, определяющие разрешения как биты и извлекающие целочисленное значение разрешения из столбца. Тогда вы получите что-то вроде этого:

  if ($ user-> permissions & \ MyNamespace \ Role :: FINISHED_DELETE) {
  
}
  

Здесь мы предполагаем, что у нас есть класс \ MyNamespace \ Role , определенный и загруженный с такими константами:

  const FINISHED_DELETE = 1;
const FINISHED_EDIT = 2;
const DRAFT_PUBLISH = 8;
...
const CHANGE_PERMISSIONS = 512;
  

Внезапно у вас появился действительно простой способ сохранить несколько разрешений для каждого пользователя без использования дополнительных таблиц и создания ненужных накладных расходов.

Итак, как нам сохранить это в базе данных при изменении разрешений? Просто просуммируйте разрешения и сохраните их как целые числа! Человек, который может FINISHED_DELETE и FINISHED_EDIT , имеет разрешения 1 и 2 в соответствии с константами выше. Поэтому, чтобы сохранить их разрешения, вы просто суммируете их (1 + 2 = 3) и сохраняете 3 в столбце разрешений нет другого способа получить число 3 с помощью двоичных комбинаций - число 3 не может быть представлено в двоичном виде каким-либо иным образом, кроме 0011, поэтому вы можете быть на 100% уверены, что число 3 всегда означает, что у пользователя есть разрешение 1 и разрешение 2, соответствующие их значениям в константах.

Это кажется слишком простым и практичным, правда? В чем подвох?

Предупреждения

Есть два основных предостережения:

  1. Вы должны помнить об использовании степени двойки при вычислении значения следующего бита разрешения.Поэтому, если вам нужно добавить новое разрешение, вы не можете просто волей-неволей выбрать 543, если у вас уже есть 512 - оно должно быть 1024. Это становится немного сложнее, когда числа становятся больше.
  2. Поскольку наши компьютеры работают под управлением 64-битных операционных систем на 64-битных процессорах (в большинстве случаев - некоторые даже застряли на 32-битных!), Это означает, что число может иметь максимум только 64 бита. Это означает, что вы можете хранить только перестановки с максимум 64 разрешениями для данного пользователя. Для малых и средних сайтов этого вполне достаточно, но на огромных сайтах это может стать проблемой.Решение состоит в том, чтобы использовать разные столбцы для разных контекстов разрешений ( draft_permissions , account_permissions и т. Д.). Каждый из этих столбцов может содержать собственные перестановки из 64 разрешений, что достаточно даже для самых требовательных веб-сайтов.

Заключение

Побитовые операции определенно все еще имеют место в современном программировании. Хотя использование чего-то столь сложного на первый взгляд может показаться нелогичным (на самом деле это не так - это просто не так хорошо знакомо, как современные таблицы соединений), этот подход дает много преимуществ, не последней из которых является резкое повышение производительности как в отношении данных. размер (намного меньше информации для хранения в базе данных и последующего извлечения) и скорость (для пользовательского объекта может быть предварительно выбрано значение разрешения - это просто int - и, следовательно, его можно проверять в любое время).

Пакеты

, представленные здесь, безусловно, упрощают работу, но только в том случае, если вы еще не знакомы с еще более простыми альтернативами, подобными показанным выше.

Как вы относитесь к использованию побитовых операторов для проверки разрешений и такого подхода к их хранению? Какие-нибудь очевидные плюсы / минусы? Сообщите нам, как вы это делаете и почему!

выражений и операторов: побитовые операторы

Hack предоставляет ряд побитовых операторов. Они предполагают, что их операнды: int .

Побитовое И

Оператор и выполняет побитовое И для своих двух операндов int и выдает int . Например:

  0b101111 & 0b101 // результат 0b101

$ lcase_letter = 0x73; // строчные буквы'
$ ucase_letter = $ lcase_letter & ~ 0x20; // очищаем 6-й бит, чтобы заглавная буква была 'S'
  

Побитовое ИЛИ

Оператор | выполняет поразрядное ИЛИ над двумя операндами int и производит int .0b101 // результат 0b101010

Переключающий

Оператор << выполняет побитовый сдвиг влево. Требуется два int операндов и производит int .

e1 << e2 сдвигает e1 влево на e2 бит, ноль расширяет значение.

  0b101 << 2 // результат 0b10100
10 << 3 // результат 80
  

Оператор >> выполняет побитовый сдвиг вправо.

  0b1011 >> 2 // результат 0b10
100 >> 2 // результат 25
  

Обратите внимание, что сдвиг вправо увеличивает знаковый бит:

  (1 << 63) >> 63 // результат -1
  

Это потому, что 1 << 63 равно 0x8000000000000000 или -

72036854775808. 

Побитовое отрицание

Оператор ~ выполняет побитовое отрицание для своего операнда int и производит int .Например:

  $ lLetter = 0x73; // строчные буквы'
$ uLetter = $ lLetter & ~ 0b100000; // очищаем 6-й бит, чтобы заглавная буква была 'S'
  

битовый сдвиг (левый сдвиг, правый сдвиг)

битовый сдвиг (левый сдвиг, правый сдвиг) | Торт для интервью

Сдвиг на бит перемещает каждую цифру в двоичное представление числа слева или справа. Есть три основных типа смен:

Левый сдвиг

При сдвиге влево старший бит теряется, и На другой конец вставлен 0 бит.

Оператор сдвига влево обычно записывается как «<<».

0010 << 1 → 0100 0010 << 2 → 1000

Один сдвиг влево умножает двоичное число на 2:

0010 << 1 → 0100 0010 это 2 0100 это 4

Логические сдвиги вправо

При переключении вправо с логическим сдвигом вправо , наименее значимый бит теряется, а 0 вставлен на другом конце.

1011 >>> 1 → 0101 1011 >>> 3 → 0001

Для положительных чисел один логический сдвиг вправо делит число на 2, выбрасывая остатки.

0101 >>> 1 → 0010 0101 это 5 0010 - 2

Арифметические сдвиги вправо

При переключении вправо с арифметическим правом сдвиг , наименее значимый бит теряется и старший бит копируется .

Языки обрабатывают арифметику и логический сдвиг вправо. различные пути. Java предоставляет два оператора сдвига вправо: >> делает арифметический сдвиг вправо и >>> выполняет логический сдвиг вправо .

1011 >> 1 → 1101 1011 >> 3 → 1111 0011 >> 1 → 0001 0011 >> 2 → 0000

Первые два числа имели 1 как наиболее значащий бит, поэтому было вставлено больше единиц во время смены. Последние два числа имели 0 как самый старший бит, поэтому сдвиг вставлен больше 0-х.

Если число закодировано с использованием два дополнения, то арифметический сдвиг вправо сохраняет знак числа, в то время как логический сдвиг вправо делает число положительным.

// Арифметический сдвиг 1011 >> 1 → 1101 1011 это -5 1101 это -3 // Логический сдвиг 1111 >>> 1 → 0111 1111 это -1 0111 это 7

Предстоит интервью?

Пройдите бесплатный 7-дневный ускоренный курс по электронной почте. Вы ​​научитесь мыслить алгоритмически , чтобы вы могли разобраться в сложном собеседовании по программированию вопросов.

Никакого предварительного обучения информатике не требуется - мы быстро научим вас, пропуская все чрезмерно академический материал.

Без спама. Отписаться в один клик в любое время.

Ты в! Зайдите в свой почтовый ящик прямо сейчас, чтобы прочитать день первый!

{"id": 21839419, "username": "2021-08-24_06: 19: 50_aktdwh", "email": null, "date_joined": "2021-08-24T06: 19: 50.877233 + 00: 00", " first_name ":" "," last_name ":" "," full_name ":" "," short_name ":" friend "," is_anonymous ": true," is_on_last_question ": false," percent_done ": 0," num_questions_done ": 0, «num_questions_remaining»: 46, «is_full_access»: false, «is_student»: false, «first_payment_date»: null, «last_payment_date»: null, «num_free_questions_left»: 3, «terms_has_agreed_to_latest»: false , "предпочтительный_editor_language": "", "is_staff": false, "auth_providers_human_readable_list": "", "num_auth_providers": 0, "auth_email": ""}

×

Войти / зарегистрироваться

Всего за пару кликов.

Мы никогда не будем публиковать сообщения на вашей стене или писать сообщения вашим друзьям.

Где мне ввести свой пароль?

На самом деле, мы не поддерживаем вход по паролю. Никогда не было. Только методы OAuth, указанные выше. Почему?

  1. Легко и быстро. Нет потока «сбросить пароль». Нет пароля, который нужно забыть.
  2. Это позволяет нам избежать хранения паролей, к которым могут получить доступ хакеры, и использовать их, чтобы попытаться войти в электронную почту или банковские счета наших пользователей.
  3. Одному человеку становится сложнее поделиться платной учетной записью Interview Cake с несколькими людьми.
«Я начал работать в Google на этой неделе! Интервью Cake был основным инструментом обучения, который я использовал перед собеседованием на месте, и он хорошо подготовил меня к тому, о чем они просили.- Виктор

. . .

Использование оператора XOR в PHP

В PHP существуют различные типы операторов для выполнения логических операций. Это AND, OR, NOT и XOR. Эти операторы используются как логический и побитовый. В этом руководстве основное внимание уделяется использованию оператора XOR .'Символ используется между операндами для выполнения побитовой операции xor. В этом руководстве показано, как можно использовать оператор xor для логических и побитовых операций.

xor Оператор:

Оператор Xor используется в логической операции, а побитовая операция показана в следующей таблице.

Условие-1 / Операнд-1 Условие-1 / Операнд-1 Выход
Истинно или 1 Верно или 1 Ложь или 0
Истинно или 1 Ложь или 1 Верно или 1
Ложь или 0 Верно или 1 Верно или 1
Ложь или 0 Ложь или 0 Ложь или 0

Использование XOR для логической операции:

Различные варианты использования оператора XOR объясняются в этом разделе этого руководства на нескольких примерах.

Пример -1: Использование XOR в логических условиях строковых данных

В следующем примере показано использование оператора xor для проверки логической логики строковых данных. Переменные $ customer_id и $ client_id инициализируются здесь строковыми данными. Первое условие if с оператором xor будет проверять первые два символа $ customer_id : ‘AL’ или ‘CA’. Оператор Xor вернет истину для этого , если условие , потому что одно условие возвращает истину.Второе условие if с оператором xor будет проверять первые два символа $ customer_id : ‘AZ’ или ‘GA’. Оператор Xor вернет false для этого , если условие , потому что оба условия возвращают false. Третье условие if с оператором xor будет проверять первые два $ customer_id - «CA» или $ client_id - «HI». Оператор Xor вернет false для этого , если условие , потому что оба условия возвращают true.

// Инициализируем переменные
$ customer_id = 'CA-756345';
$ client_id = 'HI-98765';

// XOR вернет истину, если только одно условие вернет истину
if (substr ($ customer_id, 0,2) == 'AL' xor substr ($ customer_id, 0,2) == 'CA')
{
// Узнаем, какое условие вернуло истинное значение
if (substr ($ customer_id, 0,2) == 'AL')
echo "Клиент ($ customer_id) живет в Алабаме
" ;
else
echo "Клиент ($ customer_id) живет в Калифорнии
";
}
// XOR вернет false, если оба условия вернут false
if (substr ($ customer_id, 0,2) == 'AZ' xor substr ($ customer_id, 0,2) == 'GA')
echo " Клиент ($ customer_id) проживает в Аризоне или Джорджии
";
else
echo "Клиент ($ customer_id) не живет ни в Аризоне , ни в Джорджии
";
// XOR вернет ложь, если оба условия вернут истину
if (substr ($ customer_id, 0,2) == 'CA' xor substr ($ client_id, 0,2) == 'HI')
{
if ( substr ($ customer_id, 0,2) == 'CA')
echo "Клиент ($ customer_id) живет в Калифорнии
";
else
echo "Клиент ($ customer_id) живет на Гавайях
";
}
else
{
// Узнаем состояния клиента и клиента
if (substr ($ customer_id, 0,2) == 'CA' и substr ($ client_id, 0,2) == 'HI')
{
echo "Клиент ($ customer_id) живет в Калифорнии
";
echo "Клиент ($ client_id) живет на Гавайях
";
}
}
?>

Выход:

После запуска сценария появится следующий вывод.

Пример-2: Использование XOR в логических условиях числовых данных

В следующем примере показано использование оператора xor для проверки логической логики числовых данных. Переменным $ num1 и $ num2 присваиваются два числовых значения. Первое условие if с оператором xor проверит, что $ num1 меньше 3 или больше 9. Оператор xor вернет истину для этого условия if , потому что $ num1 больше 9.Второе условие if с оператором xor проверит, что $ num1 меньше или равно 10 или $ num2 больше или равно 7. Оператор xor вернет false для этого , если условие потому что оба условия верны. Третье условие if с оператором xor проверит, что $ num1 больше 19 или $ num2 равно 17. Оператор xor вернет false для этого , если условие , потому что оба условия ложны.

// Инициализируем числовые значения
$ num1 = 10;
$ num2 = 7;
// Возвращает истину, если одно условие истинно
if ($ num1 9)
echo "Число равно $ num1.
";

// Возвращает истину, если кобусловия верны
if ($ num1 = 7)
{
if ($ num1 <= 10)
echo "Условие истинно для $ num1.
";
else
echo "Условие верно для $ num2.
";
}
else
{
if ($ num1 = 7)
echo "Оба условия верны.
";
else
echo" Оба условия ложны.
";
}

// Возвращает false, если оба условия ложны
if ($ num1> 19 xor $ num2 == 17)
{
echo "Одно из условий истинно.
";
}
else
{
if (! ($ Num1 8))
echo "Оба условия ложны.
";
else
echo "Оба условия верны.
";
}

?>

Выход:

После запуска сценария появится следующий вывод.$ number2);
// Распечатать результат в двоичном формате
echo "Результат побитовой операции в двоичном формате: $ result";
?>

Выход:

После запуска сценария появится следующий вывод.

Вывод:

Использование оператора Xor между логическими условиями и двоичными числами было объяснено на нескольких примерах в этом руководстве. Читатели поймут логику оператора xor и применит ее к условному оператору и побитовой операции после прочтения этого руководства.

Битовая строка PHP: манипулирование строками последовательностей двоичных цифр

В этом пакете представлены два класса: BitString и BitStringIterator .

Битовая строка может принимать на входе строку или другую битовую строку. Младший бит в строке будет младшим значащим битом первого байта строки; старший бит будет старший бит последнего байта строки.

Это может показаться противоестественным, поскольку мы ожидаем обратной ситуации.Однако строка внутренне преобразован в массив целых чисел с прямым порядком байтов (4 байта в 32-битных системах, 8 байтов в 64-битные).

Первоначальной целью этого класса было получение значений цвета из потока байтов; каждый цвет имеющий количество битов на компоненты и количество компонентов на цвет (например, 24-битные Цвета RGB имеют количество битов на компоненты, равное 8, и количество компонентов на цвет, равное 3, один для каждого из красного, зеленого, синего компонентов).

В любом случае, его можно использовать для получения любой части битов в битовой строке с помощью BitString :: GetBits метод. Класс BitStringIterator был разработан для получения таких вещей, как значения цветов, но может быть используется для других целей.

Эти классы были разработаны с учетом производительности; по этой причине не более 32 битов могут получать сразу методом GetBits () на 32-битных платформах и не более 64 на 64-битных платформы.Это не проблема дизайна, а выбор дизайна.

В своем текущем состоянии класс BitString действует как класс только для чтения: он только извлекает биты из потока битовой строки.

В будущем будут добавлены дополнительные функции, такие как установка битов или выполнение побитовых операций с другими битовыми строками.

BitString класс

Методы

Конструктор
  $ bitstring = новая BitString ($ data, $ data_size_in_bits = false, $ filler = 0);
  

Создает битовую строку на основе предоставленных строковых данных.Позже к данным можно будет получить доступ одним из следующих способов:

  • Вызывая метод GetBits () для получения группы битов
  • Используя оператор доступа к массиву для получения отдельного бита
  • Используя интерфейс итератора для получения отдельных битов

Параметры следующие:

  • $ data (строка или BitString ): данные, которые будут использоваться для построения BitString.Это может быть: - Строка, которая будет преобразована в целочисленные значения размера PHP \ _INT_ \ SIZE в обратном порядке. - Существующий объект BitString, который будет продублирован.
  • $ data \ _size \ _in \ _bits ( целое число ): Если не указано, общее количество битов будет равно длине $ data 8. Если указано, указывает точное количество битов, которое следует учитывать; $ data будет усечено, если этот параметр короче, чем strlen ($ data) *, и расширен значением заполнителя, если оно больше.
  • $ заполнитель ( байт ): значение-заполнитель для неустановленных битов, заданное как байт. Это значение используется, когда общее количество битов не помещается на границе байта или когда $ data необходимо развернуть, потому что $ data \ _size \ _in \ _bits больше, чем strlen ($ data) 8 . Значение false , null * или пустая строка интерпретируется как 0x00.
GetBits
  общедоступная функция GetBits ($ offset, $ bit_count)
  

Возвращает $ bit \ _count бит, начиная с указанного смещения в BitString.

Интерфейсы

Счетное

Функция count () , примененная к объекту BitString , вернет фактическое количество битов.

ArrayAccess

Позволяет получить доступ к объекту BitString как к массиву и получить каждый бит. В следующем примере выводятся все биты BitString:

  $ bs = новый BiString ("ABCDEF");
  
  для ($ i = 0; $ i  
Итератор

Позволяет перебирать каждый бит объекта BiString , используя конструкцию foreach () .В следующем примере выводятся все биты BitString:

  $ bs = новый BiString ("ABCDEF");
  
  foreach ($ bs как $ bit)
echo $ bit;
  

BitStringIterator, класс

Позволяет перебирать объект BitString и получать группы битов в виде массива.

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

Конструктор

  $ iterator = новый BitStringIterator ($ data, $ bits_per_component, $ component_count = 1);
  

Класс BitStringIterator позволяет перебирать BitString группами по $ битов \ _ на \ _компонент бит.

Массив из элементов $ component \ _count будет возвращен на каждой итерации.

Параметры следующие:

  • $ data (строка или BitString ): BitString для итерации.Если указана простая строка, она будет внутренне преобразована в объект BitString .
  • $ bits \ _per \ _component ( целое число ): количество битов на компонент.

$ component \ _count ( целое число ): количество компонентов, имеющих $ битов \ _per \ _component бит, возвращаемых при каждой итерации.

Ruby's Bitwise Toolbox: операторы, приложения и фокусы

Вероятно, вы могли бы потратить всю свою жизнь на создание приложений Rails и никогда не использовать какие-либо побитовые операторы.Если вы новичок в программировании, возможно, вы даже не знаете, что означает «побитовое».

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

Кроме того, чтобы по-настоящему понять, как компьютер складывает два числа, вы должны понимать побитовые операции.

Поскольку Ruby и многие другие языки имеют встроенную поддержку, они являются отличным инструментом для добавления в ваш набор инструментов, даже если они нужны только для понимания того, что происходит, если вы столкнетесь с ними в будущем.

В этой статье мы рассмотрим, что такое побитовые операции, некоторые примеры того, где они могут быть применены и как мы можем наилучшим образом использовать их в Ruby. Давай начнем.

Что такое побитовые операции?

На самом низком уровне любого компьютера у нас есть только единицы и нули, также известные как биты. Любая другая операция, которую мы используем в Ruby или любом другом языке программирования, в конечном итоге сохраняется в виде единиц и нулей, но программное обеспечение на наших компьютерах эффективно преобразует их между тем, что мы видим, и тем, что на самом деле сохраняется.Например, мы храним строку «hello» как цепочку из единиц и нулей.

Побитовые операции позволяют нам напрямую обращаться к этим битам, обычно представляющим числа, и делать с ними «что-то». Некоторые операции помогут нам более элегантно и эффективно реализовать функции нашего программного обеспечения.

На данный момент следует выделить два важных аспекта поразрядных операций: они чрезвычайно эффективны при хранении информации, поскольку мы используем биты напрямую, и они очень быстро выполняются.

Основное поведение - наличие набора битов и применение к нему оператора. Вы также можете использовать операторы с двумя наборами бит. Посмотрим на некоторые операции:

НЕ побитовая операция

Это унарная операция, что означает, что она применяется только к набору битов и так же проста, как замена единиц на нули и наоборот. Он представлен символом: ~ .

И побитовая операция

AND - операция, которая применяется к двум наборам битов; его символ - и , и он следует этой логике:

  1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
  

Итак, когда у нас есть два набора битов одинаковой длины, результат просто применяет эту логику к каждой отдельной паре:

в рубинах:

  25.to_s (2) # 11001
30.to_s (2) # 11110
(25 и 30) .to_s (2) # 11000
  

Побитовая операция ИЛИ

Подобно операции И, другой операцией, которая также применяется к двум наборам битов, является побитовое ИЛИ. Его символ - | и следует этой логике:

  1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
  

Итак, если у нас 1 с обеих сторон, результат будет 1, иначе - 0. Очень просто! Давайте посмотрим на операцию ИЛИ с большим количеством битов:

И в Рубине:

  25.to_s (2) # 11001
30.to_s (2) # 11110
(25 | 30) .to_s (2) # 11111
  

Практический пример 1: Разрешения

На этом этапе у вас может возникнуть вопрос, почему эти операции полезны. В конце концов, они кажутся довольно низкоуровневыми. Возможно, вы не планируете напрямую работать с сетевыми протоколами, графикой или криптографией.

Но вы, наверное, раньше работали с разрешениями. Разрешения - это одна из областей, где побитовые операции могут быть действительно полезны. Представьте, что у вас есть система разрешений, в которой пользователи могут выполнять различные действия с документом:

  • Посмотреть
  • Редактировать
  • Удалить
  • Пригласить других

А теперь мы хотим смоделировать эти действия в разных ролях:

  • Помощник: может просматривать и редактировать документ.
  • Наблюдатель: может только просматривать документ.
  • Автор: может выполнять все действия.

Как это можно смоделировать? Как мы узнаем в любой момент, есть ли у пользователя одна из этих ролей? Один из ответов - использовать побитовые операции.

Мы будем хранить только один набор битов для каждого пользователя, который представляет права, которые у них есть:

  (начиная с правой стороны)
1-й бит: просмотр
2-й бит: Изменить
3-й бит: Удалить
4-й бит: приглашать других пользователей
  

Например:

  0001 = Можно только просматривать документ.0011 = Может просматривать и редактировать документ.
1001 = Может просматривать, не может редактировать, не может удалять и может приглашать других.
  

После того, как мы установим эти значения для некоторых пользователей, мы сможем провести действительно быстрые сравнения с нужным нам разрешением. Представим, что мы проверяем, может ли пользователь редактировать документ. Мы могли бы использовать побитовую операцию И:

  # Это называется битовой маской. Он содержит только то значение, которое мы хотим проверить, в данном случае второй бит для редактирования.
EDIT_PERMISSION_MASK = 0b0010

# Мы можем определить быстрый способ это проверить:
def can_edit_document? (user_permisions)
  (EDIT_PERMISSION_MASK & user_permisions)! = 0
конец
  

Это означает, что если побитовая операция И дает нам значение, отличное от 0, у нас установлен этот бит:

  0010 И
1101
----
0000 == 0, поэтому у нас нет разрешения

0010 И
1110
----
0010! = 0, значит, у нас есть разрешение
  

Мы могли бы применить ту же логику к любому другому разрешению, изменив положение бита, который мы хотим проверить, так что мы получим эту константу и соответствующие методы:

  VIEW_PERMISSION_MASK = 0b0001
EDIT_PERMISSION_MASK = 0b0010
DELETE_PERMISSION_MASK = 0b0100
INVITE_PERMISSION_MASK = 0b1000
  

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

Например, мы сказали ранее, что помощник может только просматривать и редактировать документ, поэтому разрешения для этого пользователя будут: 0011 . Мы можем сохранить это значение в нашей базе данных, и тогда мы сможем легко проверить, может ли помощник выполнить действие с помощью методов, определенных ранее.

  ASSISTANT_MASK = VIEW_PERMISSION_MASK | EDIT_PERMISSION_MASK
# Это будет: 0011

# При желании мы можем использовать этот метод, чтобы проверить, является ли этот пользователь помощником. Этот метод можно определить внутри класса User.def is_assistant? (пользователь)
  (user.permissions == ASSISTANT_MASK)
конец
  

Если все это звучит знакомо, это потому, что это тот же подход, который обычно используется для прав доступа к файлам в системах на основе Unix.

Практический пример 2: Позиции в команде

Давайте еще немного воспользуемся побитовыми операциями 😉.

Мы можем применить их в другом относительно распространенном случае: разные должности в спортивной команде или должности в компании. Давайте для упрощения выберем баскетбольную команду.

В баскетболе есть 5 позиций при игре: - Разыгрывающий - Атакующий защитник - Маленький форвард - Мощность вперед - Центр

И мы можем присвоить каждой позиции набор битов: 00001 разыгрывающий 00010 Стрелок 00100 Легкий форвард 01000 Мощность вперед 10000 Центровой

То же самое в Ruby будет:

  POINT_GUARD_POSITION = 0b00001
SHOOTING_GUARD_POSITION = 0b00010
SMALL_FORWARD_POSITION = 0b00100
POWER_FORWARD_POSITION = 0b01000
CENTER_POSITION = 0b10000

POINT_GUARD_POSITION | SHOOTING_GUARD_POSITION | SMALL_FORWARD_POSITION | POWER_FORWARD_POSITION | CENTER_POSITION # = 31
  

Итак, теперь мы можем сделать кое-что интересное, например, проверить, присутствует ли вся команда:

  № p1.х = 0,

Смена

Это интересная группа операций, при которой мы «перемещаем» биты в одну или другую сторону в пределах набора. Позволь мне объяснить.

С битовым сдвигом мы перемещаем или «сдвигаем» биты в одном направлении, влево или вправо:

  00010111 левый сдвиг
<-------
00101110
  
  10010111 правый сдвиг
------->
11001011
  

Мы можем перемещать или сдвигать биты n раз. Вот сдвиг влево, примененный к числу 5 дважды в Ruby:

  5.to_s (2) # 101
(5 << 2) .to_s (2) # 10100
  

Как видите, сдвиг влево представлен знаком <<. При сдвиге вправо используется >>:

.
  5.to_s (2) # 101
(5 >> 2) .to_s (2) # 1
  

В этом случае мы получаем только один, потому что биты «0» и «1» из 1 * 01 * были отброшены.

Разделить на 2 со сдвигом вправо

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

Если применить сдвиг вправо к числу, мы получим результат его деления на 2:

  10.to_s (2) # 1010
(10 >> 1) .to_s (2) # 101
10 >> 1 # 5
  

Умножить на 2 со сдвигом влево

Таким же образом мы можем умножить на 2 со сдвигом влево:

  10.to_s (2) # 1010
(10 << 1) .to_s (2) # 10100
10 << 1 # 20
  

Быстро проверьте, четное или нечетное число

Есть очень простой пример поразрядной операции, которой очень легко и быстро следовать.

Представьте, что мы выполняем операцию И с 1, просто 1. Таким образом, это будет любое количество нулей, в зависимости от компьютера, в котором мы находимся, и 1. Давайте сделаем это с 2:

  2 = 00000010 &
    00000001
-------------
    00000000
  

Теперь с 4:

  4 = 00000100 &
    00000001
-------------
    00000000
  

А как насчет 5?

  5 = 00000101 &
    00000001
-------------
    00000001
  

Теперь у нас есть 1.Вы можете догадаться, что это значит?

Выполнив это И с 1, если число четное, мы получим 0. Если оно нечетное, мы получим 1. Мы могли бы легко использовать этот факт для создания пары методов в Ruby:

  def is_odd? (Число)
  номер 1
конец
  
  def is_even? (Число)
  is_odd? (число) == 0
конец
# Или:
def is_even? (число)
  (число & 1) == 0
конец
  

Если вы хотите пойти дальше или испытать умопомрачительные моменты с битами, ознакомьтесь с этой коллекцией побитовых хаков, чтобы узнать о других трюках.

Заключение

Побитовые операции трудно отслеживать, если вы никогда с ними не сталкивались, но как только вы ознакомитесь с ними, вы будете лучше подготовлены к работе с существующими или будущими проектами, в которых они используются. Кроме того, у вас будет новый инструмент при планировании решения проблемы в вашем коде.

.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *