There are many questions on the net that refer to the differences between bitwise and logical operators. Hoping that I have done a good search, none of them specialize to whether they are the same or not when used inside conditional statements nor refer exclusively to C Language. The majority referred to C++ and C# and I do not know if the same answers were applicable to C Language too.
This is an example code I wrote to test what is going on:
// Difference between logical && and bitwise & //
#include <stdio.h>
#define TRUE 123>45
#define FALSE 4>2342
void print_tt(int table[][4]);
int main(void) {
int and_tt[2][4]; // AND truth table
int or_tt[2][4]; // OR truth table
// Create truth table for logical and bitwise AND operator all in one 2d array
and_tt[0][0] = TRUE && TRUE ? 1 : 0;
and_tt[0][1] = TRUE && FALSE ? 1 : 0;
and_tt[0][2] = FALSE && TRUE ? 1 : 0;
and_tt[0][3] = FALSE && FALSE ? 1 : 0;
and_tt[1][0] = TRUE & TRUE ? 1 : 0;
and_tt[1][1] = TRUE & FALSE ? 1 : 0;
and_tt[1][2] = FALSE & TRUE ? 1 : 0;
and_tt[1][3] = FALSE & FALSE ? 1 : 0;
// Create truth table for logical and bitwise OR operator all in one 2d array
or_tt[0][0] = TRUE || TRUE ? 1 : 0;
or_tt[0][1] = TRUE || FALSE ? 1 : 0;
or_tt[0][2] = FALSE || TRUE ? 1 : 0;
or_tt[0][3] = FALSE || FALSE ? 1 : 0;
or_tt[1][0] = TRUE | TRUE ? 1 : 0;
or_tt[1][1] = TRUE | FALSE ? 1 : 0;
or_tt[1][2] = FALSE | TRUE ? 1 : 0;
or_tt[1][3] = FALSE | FALSE ? 1 : 0;
puts("_______AND_______");
puts("Logical Bitwise");
print_tt(and_tt);
puts("_______OR________");
puts("Logical Bitwise");
print_tt(or_tt);
}
// prints the truth table of the bitwise and logical operator given side by side
void print_tt(int table[][4]) {
int i;
for(i=0; i<4 ; ++i) {
printf("%-10s%s\n", table[0][i] ? "true" : "false",
table[1][i] ? "true" : "false");
}
}
The program’s output is:
_______AND_______
Logical Bitwise
true true
false false
false false
false false
_______OR________
Logical Bitwise
true true
true true
true true
false false
Which proves that there are no differences between bitwise and logical operators. Changing the definition of TRUE
and FALSE
macros to include the remaining comparison operators, one can see that there is no difference again.
Therefore, if there are differences, these might be associated to the way the compiler interprets the statement or the efficiency of the code.
In conclusion, in the specific case when we have a bitwise or logical operator between two or more results of a comparison operation inside a conditional statement, which of the two should we use, mostly for greater efficiency ?
You're only checking the values
0
and1
. Try other values and you'll see differences.This prints:
Bitwise operators only work with integers. Logical operators can be used with pointers, floating point numbers, and other non-integral types.
There's also short-circuiting. The logical operators won't evaluate their second operand if the first was enough.
This prints:
Notice how
b
is printed when using&
. There is no short-circuiting so&
calls both functions, whereas&&
only callsa()
.And on a subtler note, unlike
&&
,&
does not impose an order of evaluation on its operands. The output could equally well have thea
andb
printouts reversed.If you put all of these differences aside, then yes, the operators are equivalent. In that case, do not worry about efficiency. Use whichever operators are semantically correct: the logical ones.
(If it helps ease your mind, there will be no difference in efficiency. Compilers are very smart and will certainly emit the optimal bytecode to evaluate these expressions, whichever operator you use.)
&&
is a boolean operator, while&
is a bitwise operator.&
is an and operation on two integers. Example:1100 & 1001 = 1101
, so12 & 9 = 13
.&&
only checks if both (left and right) values are TRUE (i.e. non-zero).1 & 2
for example is0
, because a binary and of 1 and 2 is 0. Example:01 & 10 = 00
While
1 && 2
is likeTRUE && TRUE
, which also equals true. So with&&
, both left and right values are "converted" to a boolean expression first and are then compared.Also, don't forget that compilers are capable of short circuiting
&&
expressions. Like this one:The right value is not evaluated, because it doesn't need to. The first one already states clearly that
variable
isisValid
, as long asisValid
is true.Read more
The reason is bitwise compares each bit separately whereas logical treats the whole bit string as one bit true or false. When looking at a bit string of one bit there is indeed no difference between logical and bitwise operators. Another way of thinking of it is bitwise operators are functions from integers to integers where logical operators are functions from booleans to booleans.
By calling
table[0][i] ? "true" : "false"
you are casting the integer into a bit. If you keep it as an integer you will see the difference between the two types of operators.