〜x +〜y ==〜(x + y)总是假的?

这个代码总是评估为false? 这两个variables都是两个补码signed int。

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

我觉得应该有一些符合条件的数字。 我试图testing-50005000之间的数字,但从来没有达到平等。 有没有办法build立一个方程来find解决scheme的条件?

将另一个replace为我的程序中的一个隐藏的错误?

为了矛盾的缘故,假定存在一些x和某些y (mod 2 n

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

通过二补*我们知道,

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

注意到这个结果,我们有,

  ~(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 

因此,矛盾。 因此,对于所有xy (mod 2 n ), ~(x+y) != ~x + ~y


*有趣的是,在一个补码运算的机器上,所有的xy都相等。 这是因为在补码下, ~x = -x 因此, ~x + ~y == -x + -y == -(x+y) == ~(x+y)

两个的补充

绝大多数计算机上,如果x是一个整数,则-x表示为~x + 1 。 等价地, ~x == -(x + 1) 。 在你的等式中做出这个代数给出:

  • 〜x +〜y ==〜(x + y)
  • – (x + 1)+ – (y + 1)= – ((x + y)+1)
  • -x-y-2 = -x-y-1
  • -2 = -1

这是一个矛盾,所以~x + ~y == ~(x + y)总是假的


也就是说,学生们会指出C不需要二进制补码,所以我们也要考虑…

一个人的补充

在补码中 , -x简单地表示为~x 。 零是一个特殊的情况,既有全零( +0 )和全1( -0 )的表示,但是IIRC,C要求+0 == -0即使它们有不同的位模式,所以这不应该是一个问题。 只需用~replace~

  • 〜x +〜y ==〜(x + y)
  • -x +(-y)= – (x + y)

所有xy都是如此

只考虑xy的最右边的位(IE。如果x == 13 ,它是基2中的1101 ,我们只会看最后一位,a 1 )然后有四种可能的情况:

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:

因为这是作业(提示:和以前的x和y交换一样),所以我会把它留给你。

x = 1,y = 1:

我也会把这个留给你。

你可以certificate在给定任何可能的input的情况下,最右边的位在方程的左手侧和右手侧总是不同的,所以你已经certificate双方是不相等的,因为它们至less有一个被翻转从彼此。

如果位数是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. 

现在,

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

因此,他们永远是不平等的,相差1。

暗示:

x + ~x = -1 (mod 2 n

假设这个问题的目标是testing你的math(而不是你的C语言规范技能),这应该让你find答案。

无论是一,二(甚至在二十二)的补充,都可以certificate:

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

现在让a = y ,我们有:

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

要么:

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

所以在二的补码中~0 = -1 ,这个命题是错误的。

在这个~0 = 0 ,这个命题是正确的。

根据丹尼斯·里奇(Dennis Ritchie)的书,C没有默认实现二进制补码。 因此,你的问题可能并不总是如此。

假设MAX_INT是由011111...111表示的int(无论有多less位)。 那么你知道~x + x = MAX_INT~x + x = MAX_INT ~y + y = MAX_INT ,所以你可以肯定地知道~y + y = MAX_INT~(x + y)之间的差别是1

C不要求二进制补码是实现的。 但是,对于无符号整数,应用类似的逻辑。 在这个逻辑下,差异永远是1!

当然,C不需要这种行为,因为它不需要二进制补码表示。 例如, ~x = (2^n - 1) - x~y = (2^n - 1) - y会得到这个结果。

啊,基本的离散math!

查看德摩根定律

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

布尔certificate非常重要!