〜x +〜y ==〜(x + y)始终为假?


153

此代码是否总是评估为false?这两个变量都是二进制补码整数。

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

我觉得应该有一些数字可以满足条件。我尝试测试之间的数字-50005000但从未实现平等。有没有办法建立方程式来找到条件的解?

将一个交换为另一个会在我的程序中引起隐患吗?


6
您想要证明吗?
Alvin Wong

26
请注意,在有符号整数溢出的情况下,这在技术上是未定义的行为。因此,true即使他们永远不能假设严格的二进制补码,它也有可能返回。
Mysticial

1
@AlvinWong是的,一个解释会很好
Steve

1
@Steve:您可以证明您已经尝试了所有组合形式的所有常见可疑物(-1、0、1、2等),以及尝试“解决”小字号问题(三位?四位?)。这无疑将使我们确信,我们不仅仅是在帮助某人获得他们未尝试先为自己赚钱的东西。:)
sarnold 2012年

4
@AlexLockwood当我第一次发布问题时,我假设将问题标记为“家庭作业”,要求人们提供线索以帮助我解决问题(如“家庭作业”标记的描述),而不仅仅是给出答案。这就是为什么我只是问这个问题的原因:)
史蒂夫(Steve)

Answers:


237

为了矛盾,假设存在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

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


*有趣的是,在具有补码算术的机器上,等式实际上对所有x和成立y。这是因为在一个人的补充下~x = -x。因此,~x + ~y == -x + -y == -(x+y) == ~(x+y)


47
当然,C不需要这种行为。因为它不需要二进制补码表示。
Billy ONeal

12
顺便说一句,平等是真正的补数。通常,NOT操作实际上不是为数字定义的,因此,将NOT与加法混合会导致不同的行为,具体取决于数字的表示形式。
nhahtdh 2012年

9
一个人可能只是将问题重述为无符号整数,然后二进制补码根本不起作用。
R .. GitHub停止帮助ICE 2012年

5
即使是简单的,恕我直言: ~x == -(x+1),那么~(x+y) == ~x + ~y意味着-(x+y+1) == -(x+1) + -(y+1)暗示-1 == -2
BlueRaja -丹尼Pflughoeft

7
@BillyONeal,不用担心,我只是在开玩笑,感谢您提到它:)。在遇到执行补码算术的机器的那一天,我会给您买一杯饮料……听起来如何?哈哈
亚历克斯·洛克伍德

113

补码

绝大多数计算机上,如果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的(+0)和全1的(-0)表示,但是IIRC,C +0 == -0即使它们具有不同的位模式也需要它,因此这不成问题。刚刚替补~使用-

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

这对所有和所有人都是正确的。xy


13
+1为实际上考虑到两个补语和一个补语在相等基础上的答案。
CVn 2012年

13
@ dan04, +0 == -0。终于在C.中有意义的事情了:)
亚历克斯·洛克伍德

32

只考虑两者的最右边位xy(即,如果,x == 13这是1101在基地2个,我们只看到了最后一位,一个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:

我也会把这个交给你。

您可以证明,在给定任何可能输入的情况下,等式的左手侧和右手侧最右边的位将始终是不同的,因此您证明了两侧不相等,因为它们至少具有被翻转的一位彼此。


27

如果位数为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。


4
@nhahtdh,以及如何定义~对非固定宽度数字的运算?
hamstergene

1
我用这些位数给出了这个答案,以便可以轻松地将其与课堂讲授的内容联系起来。请注意,〜x高度取决于用于表示该位数的位数n。因此,在尝试通过实验进行验证时,请坚持一个。
Karthik Ku​​mar Viswanathan 2012年

1
@hamstergene:我知道位数是固定的,但我的观点是不必一定是位数(8、16等)。
nhahtdh

1
这些值很容易编写程序来验证答案。只要将〜x和〜y编写为与给定的相匹配,它就适用于任何n。
Karthik Ku​​mar Viswanathan

1
@hamstergene:我的证明没有问题,只是数字给出了错误的暗示,即它仅适用于那些情况。
nhahtdh 2012年

27

暗示:

x + ~x = -1(mod 2 n

假设问题的目标是测试您的数学(而不是您的C语言阅读技能),这将使您获得答案。


2
仅在补码机上。(C标准不需
要这样做

12
@Billy:这就像在说“仅适用于两臂人”。
dan04 2012年

2
@ dan04:不,不是。我想说所有已签名的幅度和补码表示法都已不存在。但是我这样说是错误的。C标准不允许您做此假设;因此,我会说大多数情况下使这种假设成为错误代码的代码。(特别是当通常有比签名混乱更好的方式来处理带符号的数字;并且尤其是当无符号的数字在大多数情况下通常都是更好的选择时)
Billy ONeal 2012年

10

在一个和两个(甚至42个)补码中,这可以证明:

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

现在让a = y我们有:

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

要么:

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

因此在二的补码中~0 = -1,命题是错误的。

补充一点~0 = 0,这个命题是正确的。


7

根据Dennis Ritchie的书,C默认情况下不实现二进制补码。因此,您的问题可能并不总是正确的。


5

MAX_INTint表示的int 011111...111(尽管有很多位)。然后,您知道了~x + x = MAX_INT~y + y = MAX_INT,因此您将肯定知道~x + ~y和之间的区别~(x + y)1


5

C不需要实现二进制补码。但是,对于无符号整数,将应用类似的逻辑。在这种逻辑下,差异始终为1!


3

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


0

啊,基础离散数学!

查看德摩根定律

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

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

对于布尔证明非常重要!


完全是错误的。在C +中是加法,*是乘法,而不是布尔值or或and。
2012年

感谢您指出错误的运算符。现在,它已使用正确的运算符进行了更新,尽管您是正确的,因为它不适用于原始问题。
大卫·卡钦斯基

1
好吧,如果true为1且false为零,则+和*的行为与or和完全相同,而且二进制补码的行为与否相反,因此该定律仍然适用。
2012年

感谢您指出这一点,a1an。我试图思考De Morgan的定律如何仍然适用于原始问题,但是自从我学习C编程或离散数学以来已经有好几年了。
David Kaczynski 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.