Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explain why x == ~(~x + 1) + 1 (two's complement and back!)

As we all know usually negative numbers in memory represents as two's complement numbers like that

from x to ~x + 1

and to get back we don't do the obvious thing like

~([~x + 1] - 1)

but instead we do

~[~x + 1] + 1

can someone explain why does it always work? I think I can proof it with 1-bit, 2-bit, 3-bit numbers and then use Mathematical induction but it doesn't help me understand how exactly that works.

Thanks!

like image 884
Solar Dia Avatar asked Nov 06 '15 12:11

Solar Dia


2 Answers

That's the same thing anyway. That is, ~x + 1 == ~(x - 1). But let's put that aside for now.

f(x) = ~x + 1 is its own inverse. Proof:

~(~x + 1) + 1 =
(definition of subtraction: a - b = ~(~a + b))
x - 1 + 1 =
(you know this step)
x

Also, ~x + 1 == ~(x - 1). Why? Well,

~(x - 1) =
(definition of subtraction: a - b = ~(~a + b))
~(~(~x + 1)) =
(remove double negation)
~x + 1

And that (slightly unusual) definition of subtraction, a - b = ~(~a + b)?

~(~a + b) =
(use definition of two's complement, ~x = -x - 1)
-(~a + b) - 1 =
(move the 1)
-(~a + b + 1) =
(use definition of two's complement, ~x = -x - 1)
-(-a + b) =
(you know this step)
a - b
like image 132
harold Avatar answered Nov 16 '22 11:11

harold


This is because if you increment ~x (assuming no overflow). Then converting it to back to x, you've incremented relative to ~x, but decremented relative to x. Same thing applies vice versa. Assuming your variable x has a specific value, every time you increment it, relative to ~x you'll notice it decrements.

From a programmer's point of view, this is what you'd essentially witness.

Let short int x = 1         (0x0001)
then ~x = 65534             (0xFFFE)
~x + 1 =  65534 + 1         (0xFFFF)
~(~x+1) = 0                 (0x0000)
~(~x+1) + 1 = 0 + 1         (0x0001)
like image 33
Iancovici Avatar answered Nov 16 '22 12:11

Iancovici