Search code examples
cbinaryunary-operator

one's complement ~ operator in c does not flip bits correctly?


I have a chunk of code:

#include <stdio.h>

int main() {
    char i = 0b00000010; //2
    printf("%d", ~i);
}

if unary operator ~ flips all bits, ~i should be equal to 0b11111101 which is -125, but my code gives me output of -3 which in binary is 0b00000011. Can some one please explain me why?


Solution

  • Assuming two's complement to represent negative numbers (which is what your machine uses most likely):

    0b11111101 is -3, not -125.

    0b10000011 would be -125 while 0b00000011 would be 3.

    You seem to be assuming sign-magnitude, which is very uncommon.

    The ~ operator flips all bits, but what those bits mean for negative numbers depends on your system. C allows three different representations: sign-magnitude, ones' complement, and two's complement. In practice, two's complement is almost always used.


    Also, C can't really operate on chars. When you try to use a char value in an expression, it gets promoted to int first. So what's actually going on in ~i is:

    • The value of i is read (char 2).
    • It is converted to int (int 2).
    • All bits are flipped (int 0b1111111....111101, depending on how many bits your ints have (typically 32 or 64)).
    • The bits are interpreted according to two's complement representation, corresponding to -3.

    In this case the result is the same as if you'd done the operation on char first, then converted the result to int, so it makes no difference, but this is how C does it.