Bitwise operators in conditional statement

520 views Asked by At

I am trying to enter an if statement based on a bit-wise operator without changing the original bits, and am confused why what I have doesn't work.

I am checking if it least one of bits 7, 4, 2 are 0.

Working code: (it changes the original bits, which I do not want)

#include <stdio.h>

void main() {

    unsigned char ch = 0b11111111;

    ch = ~(ch | 0x6B);

    if(ch) {

        printf("%s\n", "YES");
    } 

    else {           

        printf("%s\n", "NO");        
    }

}

That prints NO (as it should) and prints YES if you change bit 7, 4, or 2 to a 0.

Non-working code:

#include <stdio.h>

void main() {

    unsigned char ch = 0b11111111;

    if(~(ch | 0x6B)) {

        printf("%s\n", "YES");
    } 
    else {

        printf("%s\n", "NO");
    }

}

I am pretty stumped as I think the two pieces of code are identical? Thanks!

2

There are 2 answers

0
Marcus Müller On BEST ANSWER

That's easy to explain:

0x6B as you write it gets interpreted as a default integer (probably 32 bit). So (ch|0x6B)== 0x000000FF==0b00000000000000000000000011111111. Hence, ~(ch|0x6B) == 0b11111111111111111111111100000000, which is not 0, hence is true.

If you, however, put that result into a char, only the lower 8 bits are saved, and hence (unsigned char) ~(ch|0x6B) == 0, which evaluates to false.

0
Weather Vane On

In the first example, you are testing a character value, after the m.s. bits of the calculation have been truncated.

In the second example 0x6B is an integer, so ch is promoted to an int for the calculation and the m.s.bits (which you invert) are considered in the test.

There is an easier (and more obvious) way to test if any of bits 7,4,2,0 are set:

if ((ch & 0x95) != 0) { ... }