Вопрос

Я часто использую ($var & 1) в моем коде, который возвращает true, если $var является нечетным числом и ложным, если это четное число.

Но что на самом деле делает «&»?

Это было полезно?

Решение

& является двоичным and.Если у вас есть двоичное значение, и вы and с другим двоичным значением, то результат будет побитовым and из двух.Пример:

  01101010
& 01011001
= 01001000

Самый правый бит — это либо 1 (в этом случае число является нечетным), либо 0, и в этом случае число четное.Если вы & число с 1, вы смотрите только на младший бит, а if проверяет, является ли число 1 или 0.Как уже упоминали другие, посмотрите на побитовые операторы, чтобы узнать, как они работают.

Другие советы

Две операции, которые являются фундаментальными для двоичных систем, — это ИЛИ и И.

OR означает «если включен либо A, либо B».Реальным примером могут быть два коммутатора, включенных параллельно.Если какой-либо из них пропускает ток, то ток проходит.

AND означает «если включены оба A и B».Реальный пример — два последовательно соединенных переключателя.Ток будет проходить только в том случае, если оба пропускают ток.

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

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

Поэтому:

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

Тогда как

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

Таким образом, операция (& 1) сравнивает самый правый бит с 1, используя логику И.Все остальные биты фактически игнорируются, потому что все И ничего — это ничто.Четное число в двоичной системе счисления также является четным числом в десятичной системе счисления (10 кратно 2).

Другие фундаментальные операции в двоичных системах включают NOT и XOR.НЕ означает «если А выключен» и является единственной формой логического элемента, который принимает только один сигнал или «параметр» вместо двух.XOR означает «если включен либо A, либо B, но не оба».А еще есть NAND, NOR и NXOR, которые по сути просто НЕ сочетаются с AND, OR и XOR, т.е. NAND означает «если A и B нет оба включены».

В программировании оператор

& means AND,
| means OR, 
~ means NOT, 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, ваши целые числа в любом случае будут иметь большую точность, чем числа с плавающей запятой.

Также интересно узнать о побитовом режиме и PHP:

/**
 * Regular
 */
echo (true && true); // 1
echo (true && false); // nothing

echo (true || false); // 1
echo (false || false); // nothing

echo (true xor false); // 1
echo (false xor false); // nothing

/**
 * Bitwise
 */
echo (true & true); // 1
echo (true & false); // 0

echo (true | false); // 1
echo (false | false); // 0

echo (true ^ false); // 1
echo (false ^ false); // 0

В дополнение к другим ответам стоит отметить, что

if(func1() && func2())

буду только звонить func2() если func1() возвращает true («ленивая оценка»), тогда как

if(func1() & func2())

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


Томасруттер отмечает (в комментариях ниже), что вам, вероятно, не следует делать последнее на практике. (A & B) не обязательно будет иметь такую ​​же правдивость, как (A && B), особенно когда A и B являются целыми числами.например, если A=1 и B=2 (оба правдивы), A и B будут ложными, тогда как A && B истинны.Кроме того, другой разработчик может подумать, что это опечатка, и «исправить» ее до двух амперсандов.

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

($var % 2) /* instead of */ ($var & 1)

Потому что это ясно дает понять, что вы проверяете, что число нечетное (не делится на два), и оно является более общим, поэтому вы можете использовать ($var % 3) таким же образом и сделать вывод, как оно работает для любого N.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top