58

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 are same as well.

Aren't they same?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Moon
  • 22,195
  • 68
  • 188
  • 269
  • 1
    They are both the same thing, they're just used for two different things to accomplish the same task. – animuson Mar 04 '10 at 01:42

6 Answers6

104

& 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
cletus
  • 616,129
  • 168
  • 910
  • 942
  • 8
    I'll add that when you are comparing booleans or integers, and treating the result as a boolean, then they *appear* to be the same. – kibibu Mar 04 '10 at 01:52
  • 1
    @kibibu: true, PHP's type juggling can complicate the comparison. – cletus Mar 04 '10 at 02:10
  • @kibibu, Does the interpreter consider them equal? Or will different machine code be runned depending on which one is used? – Pacerier Mar 30 '15 at 11:55
  • @Pacerier They are definitely different -- look at the return results in the example. In a boolean context (an if statement), the correct branch is taken, but other than that there is nothing one borrows from the other. Except at the bit level.. – Gerard ONeill Apr 16 '15 at 14:29
  • 5
    @kibibu not necessarily at all. 2 & 1 (binary 10 & 01) is 0 which is falsey, but 2 && 1 should be true if PHP is at all reasonable... – Muzer Aug 19 '15 at 08:48
62

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).

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
8

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.

tl;dr

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 and behavior may be different than , but I'll use a small program to demonstrate how compiler behaves when using Logical and Bitwise And.

Let's assume we have a program in 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.

Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
7
 

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 
Pavunkumar
  • 5,147
  • 14
  • 43
  • 69
  • what is the difference between logical and boolean bitwise? they are the same. – avasin Jun 21 '13 at 15:06
  • 1
    @avasin Logical `AND` performs a short-circuited (see Matthew Flaschen's answer) `and` operation on *the boolean values* of its operands and evaluates to a boolean value, whereas bitwise `AND` performs the `and` operation on *each individual bit* of each of its operands. So `0b0011 && 0b0110` evaluates to `TRUE`, but `0b0011 & 0b0110` evaluates to `0b0010`. – Lux Jul 31 '17 at 21:36
  • @avasin there is no *boolean bitwise* operation. – Christos Lytras Jan 29 '20 at 21:40
3

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
umar
  • 4,309
  • 9
  • 34
  • 47
0

&& 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.)

Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
blobbo
  • 9
  • 1