2009-03-01 7 views
47

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

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

+0

Для некоторых вопрос не прост, и он просит подробного объяснения об операторе, как вы можете видеть по его ответу. –

+0

@ Олафур - оператор & довольно прост. Он не хочет подробного объяснения, ему нужно объяснение AN, потому что он использовал его, не зная, что именно он делает. Хотя я восхищаюсь его готовностью признать, что он не знает этого и не хочет его изучать, это еще вопрос Google. –

+0

Дело не в том, что ответ прост, но если его размещение здесь означает просто копирование его из другого места. Это избыточно. Мне кажется, что некоторые люди действительно используют СО, чтобы убить свободное время. Может быть, я немного предвзятый, но мне нравится SO для головоломок, а не для чат-подобных вопросов. – Caffeine

ответ

52

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

01101010 
& 01011001 
= 01001000 

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

18

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

Этот ответ на самом деле не объясняет, как && отличается и очень хорошо, на мой взгляд. && отбрасывает оба параметра в boolean и сравнивает один бит. & сравнивается поразмерно: каждый бит в одном параметре сравнивается с каждым битом в другом. – thomasrutter

+3

«regular» известен как логический и/или –

+1

. Также важно знать, что побитовые операторы, такие как & и | работают с целыми числами. Примеры в этом ответе работают только потому, что 'true' преобразуется в' 1' и 'false' преобразует в' 0'. Если у вас есть 'echo (« cheese »& 4)', он выдаст нуль, а 'echo (« cheese »&& 4)' будет выдавать true. – thomasrutter

24

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

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

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

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

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

Вот почему:

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

В то время как

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

The (& 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 конкретные примечания

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

+2

Лично я думаю, что это объясняет проблему лучше, чем принятый ответ, поскольку она фактически объясняет, какие поразрядные операции выполняются за кулисами, что крайне важно ** для понимания и использования. – Byson

11

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

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

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

11

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

if(func1() && func2()) 

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

if(func1() & func2()) 

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


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

+1

+1, это очень интересно и не известно всем – dgraziotin

+0

Важное различие. –

+1

Хотя это работает * большую часть времени *, оно не всегда будет работать, например, когда функции возвращают числа. Скажем func1() возвращает 1, а func2() возвращает 4. 'func1() && func2()' будет оценивать 'true', а' func1() и func2() 'будет оцениваться' 0'. Даже в тех случаях, когда это действительно работает, я бы не назвал его хорошей практикой кодирования, поскольку он полагался на побочные эффекты порядка оценки и преобразования типов, что усложняло чтение и понимание цели кода. Любой человек, просматривающий код, может считать, что это опечатка. – thomasrutter