此代码是否总是评估为false?这两个变量都是两个补码签名的整数。
~x + ~y == ~(x + y)
我觉得应该有一些符合条件的数字。我尝试测试-5000
和5000
之间的数字,但从未实现过相等。有没有办法建立一个方程来找到条件的解?
将另一个换成另一个会导致我的程序中出现一个阴险的错误吗?
答案 0 :(得分: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
和x
{mod 2 n ),y
。
*值得注意的是,在具有一个补码算术的机器上,所有x
和y
的相等性实际上都成立。这是因为在一个补码下~x = -x
。因此,~x + ~y == -x + -y == -(x+y) == ~(x+y)
。
答案 1 :(得分:113)
在浩大的大多数计算机上,如果x
是整数,则-x
表示为~x + 1
。同等地,~x == -(x + 1)
。在你的等式中进行这种替换给出了:
这是一个矛盾,因此~x + ~y == ~(x + y)
总是错误。
那就是说,小学生会指出C不需要两个补码,所以我们也要考虑......
在one's complement中,-x
仅表示为~x
。零是一种特殊情况,具有全0(+0
)和全-1(-0
)表示,但IIRC,C需要+0 == -0
,即使它们具有不同的位模式,所以这应该不是问题。只需将~
替换为-
。
x
和y
true 。
答案 2 :(得分:32)
仅考虑x
和y
中最右边的位(IE。如果x == 13
在基数2中为1101
,我们只会查看最后一位, a 1
)然后有四种可能的情况:
x = 0,y = 0:
LHS:~0 + ~0 =&gt; 1 + 1 =&gt; 10个
RHS:〜(0 + 0)=&gt; ~0 =&gt; 1
x = 0,y = 1:
LHS:~0 + ~1 =&gt; 1 + 0 =&gt; 1
RHS:〜(0 + 1)=&gt; ~1 =&gt; 0
x = 1,y = 0:
我会把这个留给你,因为这是作业(提示:它与之前交换的x和y相同)。
x = 1,y = 1:
我也会把这个留给你。
你可以证明,在给定任何可能的输入的情况下,最右边的位在方程的左手侧和右手侧总是不同的,所以你已经证明双方都不相等,因为它们至少有一位这是彼此翻转的。
答案 3 :(得分: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 :(得分:27)
<强>提示:强>
x + ~x = -1
(mod 2 n )
假设问题的目标是测试你的数学(而不是你的阅读C规范技能),这应该可以帮助你找到答案。
答案 5 :(得分: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
的补语中,命题是正确的。
答案 6 :(得分:7)
根据Dennis Ritchie的书,C默认不实现二进制补码。因此,您的问题可能并非总是如此。
答案 7 :(得分:5)
让MAX_INT
成为011111...111
所代表的int(无论有多少位)。然后,您知道~x + x = MAX_INT
和~y + y = MAX_INT
,因此您肯定知道~x + ~y
和~(x + y)
之间的差异为1
。
答案 8 :(得分:5)
C不要求两个补码是实现的。但是,对于无符号整数,应用类似的逻辑。在这个逻辑下,差异总是1!
答案 9 :(得分:3)
当然,C不需要这种行为,因为它不需要二进制补码表示。例如,~x = (2^n - 1) - x
&amp; ~y = (2^n - 1) - y
会得到这个结果。
答案 10 :(得分:0)