~x + ~y == ~(x + y) is always false?

CBit ManipulationSignedTwos Complement

C Problem Overview


Does this code always evaluate to false? Both variables are two's complement signed ints.

~x + ~y == ~(x + y)

I feel like there should be some number that satisfies the conditions. I tried testing the numbers between -5000 and 5000 but never achieved equality. Is there a way to set up an equation to find the solutions to the condition?

Will swapping one for the other cause an insidious bug in my program?

C Solutions


Solution 1 - C

Assume for the sake of contradiction that there exists some x and some y (mod 2n) such that

~(x+y) == ~x + ~y

By two's complement*, we know that,

      -x == ~x + 1
<==>  -1 == ~x + x

Noting this result, we have,

      ~(x+y) == ~x + ~y
<==>  ~(x+y) + (x+y) == ~x + ~y + (x+y)
<==>  ~(x+y) + (x+y) == (~x + x) + (~y + y)
<==>  ~(x+y) + (x+y) == -1 + -1
<==>  ~(x+y) + (x+y) == -2
<==>  -1 == -2

Hence, a contradiction. Therefore, ~(x+y) != ~x + ~y for all x and y (mod 2n).


*It is interesting to note that on a machine with one's complement arithmetic, the equality actually holds true for all x and y. This is because under one's complement, ~x = -x. Thus, ~x + ~y == -x + -y == -(x+y) == ~(x+y).

Solution 2 - C

Two's Complement

On the vast majority of computers, if x is an integer, then -x is represented as ~x + 1. Equivalently, ~x == -(x + 1). Making this substution in your equation gives:

  • ~x + ~y == ~(x + y)
  • -(x+1) + -(y+1) = -((x + y) + 1)
  • -x - y - 2 = -x - y - 1
  • -2 = -1

which is a contradiction, so ~x + ~y == ~(x + y) is always false.


That said, the pedants will point out that C doesn't require two's complement, so we must also consider...

One's Complement

In one's complement, -x is simply represented as ~x. Zero is a special case, having both all-0's (+0) and all-1's (-0) representations, but IIRC, C requires +0 == -0 even if they have different bit patterns, so this shouldn't be a problem. Just substitute ~ with -.

  • ~x + ~y == ~(x + y)
  • -x + (-y) = -(x + y)

which is true for all x and y.

Solution 3 - C

Consider only the rightmost bit of both x and y (IE. if x == 13 which is 1101 in base 2, we will only look at the last bit, a 1) Then there are four possible cases:

x = 0, y = 0:

>LHS: ~0 + ~0 => 1 + 1 => 10
RHS: ~(0 + 0) => ~0 => 1

x = 0, y = 1:

>LHS: ~0 + ~1 => 1 + 0 => 1
RHS: ~(0 + 1) => ~1 => 0

x = 1, y = 0:

> I will leave this up to you since this is homework (hint: it is the same as the previous with x and y swapped).

x = 1, y = 1:

> I will leave this one up to you as well.

You can show that the rightmost bit will always be different on the Left Hand Side and Right Hand Side of the equation given any possible input, so you have proven that both sides are not equal, since they have at least that one bit that is flipped from each other.

Solution 4 - C

If the number of bits is n

~x = (2^n - 1) - x
~y = (2^n - 1) - y


~x + ~y = (2^n - 1) +(2^n - 1) - x - y =>  (2^n + (2^n - 1) - x - y ) - 1 => modulo: (2^n - 1) - x - y - 1.

Now,

 ~(x + y) = (2^n - 1) - (x + y) = (2^n - 1) - x - y.

Hence, they'll always be unequal, with a difference of 1.

Solution 5 - C

Hint:

x + ~x = -1 (mod 2n)

Assuming the goal of the question is testing your math (rather than your read-the-C-specifications skills), this should get you to the answer.

Solution 6 - C

In both one's and two's (and even in 42's) complement, this can be proved:

~x + ~y == ~(x + a) + ~(y - a)

Now let a = y and we have:

~x + ~y == ~(x + y) + ~(y - y)

or:

~x + ~y == ~(x + y) + ~0

Therefore in two's complement that ~0 = -1, the proposition is false.

In one's complement that ~0 = 0, the proposition is true.

Solution 7 - C

According to the book by Dennis Ritchie, C does not implement two's complement by default. Therefore, your question might not always be true.

Solution 8 - C

Letting MAX_INT be the int represented by 011111...111 (for however many bits there are). Then you know that, ~x + x = MAX_INT and ~y + y = MAX_INT, so therefore you will know for certain that the difference between ~x + ~y and ~(x + y) is 1.

Solution 9 - C

C does not require that two's complement be what is implemented. However, for unsigned integer similar logics is applied. Differences will always be 1 under this logic!

Solution 10 - C

Of course, C doesn't require this behavior because it no require two's complement representation. For example, ~x = (2^n - 1) - x & ~y = (2^n - 1) - y will get this result.

Solution 11 - C

Ah, fundamental discrete mathematics!

Check out De Morgan's Law

~x & ~y == ~(x | y)

~x | ~y == ~(x & y)

Very important for Boolean proofs!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSteveView Question on Stackoverflow
Solution 1 - CAlex LockwoodView Answer on Stackoverflow
Solution 2 - Cdan04View Answer on Stackoverflow
Solution 3 - CPaulView Answer on Stackoverflow
Solution 4 - CKarthik Kumar ViswanathanView Answer on Stackoverflow
Solution 5 - Cuser541686View Answer on Stackoverflow
Solution 6 - CypercubeᵀᴹView Answer on Stackoverflow
Solution 7 - Cuser1457474View Answer on Stackoverflow
Solution 8 - CAdrian MonkView Answer on Stackoverflow
Solution 9 - Cuser1422551View Answer on Stackoverflow
Solution 10 - Cuser1472392View Answer on Stackoverflow
Solution 11 - CDavid KaczynskiView Answer on Stackoverflow