C bitwise negation creates negative output: [duplicate]
Asked Answered
U

3

10

I am trying REALLY hard to flip the bits in a C int variable. I am doing it like so:

input = 15;

input = ~input;

printf("%d", input);

BUT IT ALWAYS SHOWS UP as -16. It should be 0! if 15 is written as 1111, why is it returning 10000?! This is maddening! Can somebody PLEASE help me!?

Urson answered 23/8, 2012 at 3:31 Comment(2)
You forgot the quotation marks on the %d format; I've added them.Lulu
It's generally best to copy-and-paste your actual working code; that neatly avoids typos and similar errors.Lulu
K
18

Since int on your system is most likely a 32-bit number, all bits are flipped, including the ones that were insignificant zeros in the original number:

00000000000000000000000000001111

becomes

11111111111111111111111111110000

This is a negative number: the most significant bit of 15 is zero, so it becomes 1 when flipped.

If you would like to keep only the bits of the original number, you need to mask with all ones in the significant positions of the number, like this:

printf("%d\n", input & 0xF);

ANDing with 0xF "cuts off" all bits except the last four.

Khiva answered 23/8, 2012 at 3:33 Comment(0)
I
5

This is occurring because input is comprised of more than four bits. If we assume that input is a signed char, with 8 bits (or one byte), then:

input == 15 == 0x0F == 0b00001111

As you can see, the 4 more significant bits of input are all 0. After a bitwise NOT operation (~), we have:

~input == -16 == 0xF0 == 0b11110000

The four bits that used to be zero are now ones, and the ones are now zeros. The most significant bit in a signed variable determines its sign (0 being positive and 1 being negative). Thus, by flipping the bits the sign has been reversed. The negative number may be read as:

1      1     1     1     0     0     0   0
-128 + 64  + 32  + 16  + 0   + 0   + 0 + 0

which resolves to the -16 that was printed.

If your homework is to zero a variable using the bitwise NOT, try declaring input as an unsigned char to avoid having to worry about the sign bit. Then, set input to 255, the highest value an 8 bit variable can hold (0xFF or 0b11111111).

Interlard answered 23/8, 2012 at 4:6 Comment(0)
L
3

15 is of type int. Depending on how big int is, the representation of 15 ends in 1111, but it starts with a bunch of 0s.

The ~ operator flips all the bits; the 1s (4 of them) become 0s, and the 0s (N-4 of them) become 1s.

Lulu answered 23/8, 2012 at 3:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.