I am confused with &
and &&
. I have two PHP books. One says that they are same, but the another says they are different. I thought they
The other answers are correct, but incomplete. A key feature of logical AND is that it short-circuits, meaning the second operand is only evaluated if necessary. The PHP manual gives the following example to illustrate:
$a = (false && foo());
foo
will never be called, since the result is known after evaluating false. On the other hand with
$a = (false & foo());
foo
will be called (also, the result is 0 rather than false).
As the others are saying, a single &
is bit-wise. It basically converts the left-hand value into its bits representation, and the right hand side into bits representation as well, then performs logical AND between them and outputs the result.
Double &&
is either true or false, (in some languages 0 or 1) if both left and right side are true (or non-zero).
I'd also add that this is not just in PHP. It is like that in many many other languages as well, like C, Java, Ruby, etc.
&&
is &
performed on operands reduced to either 1
or 0
.
(In other words, &&
is a bitwise operator under the caveat that it changes its operands. That is, logical operations are a subset of bitwise operations.)
&
is bitwise AND. See Bitwise Operators. Assuming you do 14 & 7
:
14 = 1110
7 = 0111
---------
14 & 7 = 0110 = 6
&&
is logical AND. See Logical Operators. Consider this truth table:
$a $b $a && $b
false false false
false true false
true false false
true true true
Matthew's answer about how Logical And &&
operator is the biggest difference; logical comparison will stop when it will find something that breaks the chain. In addition, one more big difference it the result type/value.
By using the Logical And &&
, it will always return a Boolean type/value, true
or false
.
false & 1 // int(0)
false && 1 // bool(false)
It is important to use Boolean type/values when returning a function with a logical result, because someone can use the Identical comparison operator ===
to compare the results (which is high likely to happen) and it will fail if you use something like this:
(false & 1) === false // bool(false)
(true & true) === true // bool(false)
Never use Bitwise And &
when you need to make a logical comparison and especially when returning values from functions with logical results. Instead use the Logical And &&
:
(false && 1) === false // bool(true)
(true && true) === true // bool(true)
When comparing characters, Logical And &&
will always result to true
, even with NUL
character, unless if it's converted to an integer:
'A' && 'B' // bool(true)
'A' && 0 // bool(false)
'A' && '\0' // bool(true)
'A' && (int)'\0' // bool(false)
If you use the Bitwise And &
with characters, it will result the character corresponding to the Bitwise And operation between those two characters:
'A' & 'B' // string(1) "@"
01000001 // ASCII 'A'
&
01000010 // ASCII 'B'
=
01000000 // ASCII '@'
Beware the usage of the Bitwise And &
when using with types other than Integers and Characters (which are special kind of integers). For example, if you use it with real numbers float/double, then it can result to 0
even if both operands are NOT 0
:
1.0 & 1.0 // int(1)
2.0 & 1.0 // int(0)
1.0 && 1.0 // bool(true)
2.0 && 1.0 // bool(true)
In addition, if we go at assembly instructions level, we can see that difference and how the compiler manages to handle so the Logical And &&
uses cmp <var>, 0
to compare and does not continue executing if one operand fails; Bitwise And uses and <var1>, <var2>
to make a bitwise result and then test if it's of 0
value. I know this question is tagged for php and php behavior may be different than c, but I'll use a small c program to demonstrate how compiler behaves when using Logical and Bitwise And.
Let's assume we have a program in c that uses both Bitwise and Logical And:
int a = 0;
int b = 1;
int c = 2;
if (a & b)
c = 3;
if (a && b)
c = 4;
The compiler will generate the following assembly opcodes (W32Dasm result for x86; I have changed the memory addresses with <variable>
names for simplicity and to be more understandable):
:0229 mov <a>, 0
:0230 mov <b>, 1
:0237 mov <c>, 2
// if (a & b) begins
:023E mov eax, <a>
:0241 and eax, <b> // a bitwise and b, result stored to eax
:0244 test eax, eax // test eax and set ZeroFlag if equals to 0
:0246 je 024F // >--- Jump if ZeroFlag is set
:0248 mov <c>, 3 // | or set c = 3
// if (a && b) begins |
:024F cmp <a>, 0 // <--- compare a to 0 and sets ZeroFlag if difference is 0
:0253 je 0262 // >--- Jump if ZeroFlag is set (a == 0)
:0255 cmp <b>, 0 // | compare b to 0 and sets ZeroFlag if differemce is 0
:0259 je 0262 // | >--- Jump if ZeroFlag is set (b == 0)
:025B mov <c>, 4 // | | or set c = 4
:0262 <program continues> // <--- <---
The compiler not only uses different instructions to compare between the Logical and Bitwaise And, but at the line :0253
in if (a && b)
logical comparison, we see that if a == 0
then it jumps and does not check for the rest operands.
So, I disagree to animuson's comment:
They are both the same thing, they're just used for two different things to accomplish the same task. – animuson Mar 4 '10 at 1:42
They are not the same thing and both are/(should be) used for specific tasks depending on the programs' logic/flow.
AND operation: & -> will do the bitwise AND operation , it just doing operation based on the bit values. && -> It will do logical AND operation. It is just the check the values is true or false. Based on the boolean value , it will evaluation the expression