Question

I can't get the 2-completement calculation to work.

I know C compiles ~b that whould invert all bits to -6 if b=5. But why?

int b=101, inverting all bits is 010 then for 2 completement's notation I just add 1 but that becomes 011 i.e. 3 which is wrong answer.

How should I calculate with bit inversion operator ~?

Similar question: How is ~(~a)=17 if a=17? We would have to do two completent calculation twice.

Was it helpful?

Solution

~b is not a 2-complement operation. It is a bitwise NOT operation. It just inverts every bit in a number, therefore ~b is unequal to -b.

Examples:

b = 5
binary representation of b:  0000 0000 0000 0101
binary representation of ~b: 1111 1111 1111 1010
~b = -6

b = 17
binary representation of b:     0000 0000 0001 0001
binary representation of ~b:    1111 1111 1110 1110
~b = -18
binary representation of ~(~b): 0000 0000 0001 0001
~(~b) = 17

OTHER TIPS

Actually, here's how 5 is usually represented in memory (16-bit integer):

0000 0000 0000 0101

When you invert 5, you flip all the bits to get:

1111 1111 1111 1010

That is actually -6 in decimal form. I think in your question, you were simply flipping the last three bits only, when in fact you have to consider all the bits that comprise the integer.

The problem with b = 101 (5) is that you have chosen one too few binary digits.

        binary | decimal  
~101 = 010     | ~5 = 2  
~101 + 1 = 011 | ~5 + 1 = 3

If you choose 4 bits, you'll get the expected result:

          binary | decimal  
~0101 = 1010     | ~5 = -6  
~0101 + 1 = 1011 | ~5 + 1 = -5

With only 3 bits you can encode integers from -4 to +3 in 2's complement representation. With 4 bits you can encode integers from -8 to +7 in 2's complement representation.

-6 was getting truncated to 2 and -5 was getting truncated to 3 in 3 bits. You needed at least 4 bits.

And as others have already pointed out, ~ simply inverts all bits in a value, so, ~~17 = 17.

~ simply inverts all the bits of a number:

~(~a)=17 if a=17
~0...010001 = 1...101110 ( = -18 )
~1...101110 = 0...010001 ( = 17 )

You need to add 1 only in case you want to negate a number (to get a 2-s complement) i.e. get -17 out of 17.

~b + 1 = -b

So:

~(~b) equals ~(-b - 1) equals -(-b - 1) -1 equals b

In fact, ~ reverse all bits, and if you do ~ again, it will reverse back.

I can't get the 2-completement calculation to work. I know C compiles ~b that whould invert all bits to -6 if b=5. But why?

Because you are using two's complement. Do you know what two's complement is?

Lets say that we have a byte variable (signed char). Such a variable can have the values from 0 to 127 or from -128 to 0.

Binary, it works like this:

0000 0000  // 0
...
0111 1111  // 127
1000 0000  // -128
1000 0001  // -127
...
1111 1111  // -1

Signed numbers are often described with a circle.

If you understand the above, then you understand why ~1 equals -2 and so on.

Had you used one's complement, then ~1 would have been -1, because one's complement uses a signed zero. For a byte, described with one's complement, values would go from 0 to 127 to -127 to -0 back to 0.

you declared b as an integer. That means the value of b will be stored in 32 bits and the complement (~) will take place on the 32 bit word and not the last 3 bits as you are doing.

    int b=5 // b in binary: 0000 0000 0000 0101  
    ~b // ~b in binary: 1111 1111 1111 1010 = -6 in decimal  

The most significant bit stores the sign of the integer (1:negetive 0:positive) so 1111 1111 1111 1010 is -6 in decimal.
Similarly:

    b=17 // 17 in binary 0000 0000 0001 0001  
    ~b // = 1111 1111 1110 1110 = -18  
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top