2

I am having trouble trying to understand how logical operators work in C. I already understand how the bit-level operators work, and I also know that logical operators treat nonzero arguments as representing TRUE and zero arguments as representing FALSE

But say we have 0x65 && 0x55. I do not understand why and how this operations gives 0x01.

I tried to convert it to binary, but I cannot figure out how it works

FranXh
  • 4,481
  • 20
  • 59
  • 78
  • 1
    Because 0x65 is not 0, neither is 0x55, && is a logical and : true and true is true so the answer is 1 – Kwariz Sep 08 '12 at 16:12

8 Answers8

2

&& operator:

If the left operand and the right operand are both different than 0 it evaluates to 1 otherwise it evaluates to 0.

If the left operand is 0, the right operand is not evaluated and the result is 0.

0x65 && 0x55 is evaluated to 1.

ouah
  • 142,963
  • 15
  • 272
  • 331
1

The && is a logical AND (as opposed to &, which is a bitwise AND). It cares only that its operands as zero/non-zero values. Zeros are considered false, while non-zeros are treated as true.

In your case, both operands are non-zero, hence they are treated as true, resulting in a result that is true as well. C represents true as 1, explaining the overall result of your operation.

If you change the operation to &, you would get a bitwise operation. 0x65 & 0x55 will give you a result of 0x45.

Aaron McDaid
  • 26,501
  • 9
  • 66
  • 88
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

&& is a logical operator, not a bitwise operator. Both 0x65 and 0x55 are true, so the result is a true number. 0x01 is a true number.

Binary representations only come into play for bitwise operations. The expression 0x65 & 0x55 is equal to 0x45.

aschepler
  • 70,891
  • 9
  • 107
  • 161
0

Any expression that evaluates to 0 is false. And any expression that is non-zero is true. So both 0x65 and 0x55 are true.

0x65 && 0x55

=> true && true => true

kjohri
  • 1,166
  • 11
  • 10
0

I tried to convert it to binary

That might have got in the way of understanding. The exact bit-patterns of 0x65 and 0x55 are completely irrelevant to the required result, all that matters is that they're both non-zero. You could consider a = (0x65 && 0x55) to be equivalent to something like:

if (0x65 != 0) goto condition_false;
if (0x55 != 0) goto condition_false;
a = 1;
goto condition_end;
condition_false:
a = 0;
condition_end:

A given implementation might be able to emit code more efficient than that (although I have seen pretty much that code emitted, with each if ... goto being a test and branch in the assembly). The more-efficient code might involve some bit operations to avoid branches. For that matter, in this example involving constants the compiler would probably just emit a = 1;.

The meaning of the && operator is in terms of conditional execution, though. For example if you write f() && g() then it is guaranteed that when f returns a false value, g is not called. If it's possible to get the same result by bit-twiddling then that's likely a bonus for performance.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
0

C and C++ has three logical operators: logical not(!), logical and(&&) and logical or(||). For logical operators, 0 is false and anything that is not zero is true. This truth table illustrates how each logical operator works(will be using 1 for true):

p     q     p && q    p || q
=     =     ======    ======
1     1       1         1
1     0       0         1
0     1       0         1
0     0       0         0

The truth table for ! is as follows:

p    !p
=    ===
1     0
0     1

For your specific case:

0x65 && 0x55

Since both operands 0x65 and 0x55 evaluate to true the whole expression evaluates to true and thus expands to 1, which applies to c99 but other answers in the linked thread explain how it applies before c99 as well.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
-1

C defines values greater than zero to be "True". As both 0x65 and 0x55 match this condition, the result is also True - which, on output, is 1 - or, in hex notation, 0x01.

An alternative style of writing for your code would be:

return (0x65 is true) and (0x55 is true);

irrenhaus3
  • 126
  • 1
  • 4
-1

As you said the logical operators treat nonzero arguments as representing

 (0x65 && 0x55) is equal as (0x65 > 0) && (0x55 > 0)

 0x65 > 0 get true and 0x55 > 0 get true as well

 So (0x65 && 0x55)  is equal true && true = 1
wbao
  • 205
  • 1
  • 5