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

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

Но что значит "&" на самом деле?

Ответ 1

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

  01101010
& 01011001
= 01001000

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

Ответ 2

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

ИЛИ означает "если включен A или B включен". Пример в реальном мире будет состоять из двух переключателей. Если любой из них пропускает ток, то ток проходит через.

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

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

При применении к целым числам каждый бит в одном числе объединяется с каждым битом в другом числе. Таким образом, чтобы понять побитовые операторы 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 с использованием логики И. Все остальные биты фактически игнорируются, потому что ничего, и ничто не является ничем. Четное число в двоичном выражении равно четному числу в десятичной нотации (10 кратно 2).

Другие фундаментальные операции с двоичными системами включают NOT и XOR. NOT означает "если A выключен" и является единственной формой логических ворот, которая принимает только один сигнал или "параметр" вместо двух. 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 float сначала будут неявно преобразованы в целые числа. Числа за пределами диапазона, которые могут быть выражены как целые числа, будут усечены до нуля, то есть все числа над PHP_INT_MAX будут выглядеть "четными" в выражении ($num & 1)). Если вы хотите поддерживать номера за пределами PHP_INT_MIN/PHP_INT_MAX, вам понадобится fmod($num, 2). Если, однако, вы на 64-битном PHP, ваши целые числа будут иметь большую точность, чем плавающие в любом случае.

Ответ 3

Это также интересно узнать о побитом и 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

Ответ 4

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

if(func1() && func2())

Вызывается только func2(), если func1() возвращает true ( "ленивая оценка" ), тогда как

if(func1() & func2())

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


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

Ответ 5

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

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

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