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

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

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

5 ответов


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

  01101010
& 01011001
= 01001000

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


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

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

и означает "если оба A и B включены". Пример реального мира - два переключателя последовательно. Течение только пройдет до конца если оба позволяют течению до конца.

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

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

это почему:

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

, тогда как

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

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


это также интересно узнать о bitwise и 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

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

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

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


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

if(func1() && func2())

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

if(func1() & func2())

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


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