为什么 gcc 没有正确添加 tmin + tmin?
Why does gcc not add tmin + tmin correctly?
当我发现这个奇怪的东西时,我一直在玩按位运算和二进制补码。
#include <stdio.h>
int main ()
{
int tmin = 0x80000000;
printf("tmin + tmin: 0x%x\n", tmin + tmin);
printf("!(tmin + tmin): 0x%x\n", !(tmin + tmin));
}
以上代码产生以下输出
tmin + tmin: 0x0
!(tmin + tmin): 0x0
为什么会这样?
0x80000000
二进制是
0b10000000000000000000000000000000
当您将两个 0x80000000
相加时,
|<- 32bits ->|
0b10000000000000000000000000000000
+ 0b10000000000000000000000000000000
------------------------------------
0b100000000000000000000000000000000
|<- 32bits ->|
然而,int
在你的机器上似乎有 32 位,所以只保留低 32 位,这意味着你的结果中的 1
被默默地丢弃。这称为 Integer Overflow.
另请注意,在 C 中,有符号(与无符号相对,即 unsigned int
)整数溢出实际上是 undefined behavior, which is why !(tmin + tmin)
gives 0x0
instead of 0x1
. See this blog post,例如,由于另一个未定义的行为,变量既为真又为假,即未初始化的变量。
当我发现这个奇怪的东西时,我一直在玩按位运算和二进制补码。
#include <stdio.h>
int main ()
{
int tmin = 0x80000000;
printf("tmin + tmin: 0x%x\n", tmin + tmin);
printf("!(tmin + tmin): 0x%x\n", !(tmin + tmin));
}
以上代码产生以下输出
tmin + tmin: 0x0
!(tmin + tmin): 0x0
为什么会这样?
0x80000000
二进制是
0b10000000000000000000000000000000
当您将两个 0x80000000
相加时,
|<- 32bits ->|
0b10000000000000000000000000000000
+ 0b10000000000000000000000000000000
------------------------------------
0b100000000000000000000000000000000
|<- 32bits ->|
然而,int
在你的机器上似乎有 32 位,所以只保留低 32 位,这意味着你的结果中的 1
被默默地丢弃。这称为 Integer Overflow.
另请注意,在 C 中,有符号(与无符号相对,即 unsigned int
)整数溢出实际上是 undefined behavior, which is why !(tmin + tmin)
gives 0x0
instead of 0x1
. See this blog post,例如,由于另一个未定义的行为,变量既为真又为假,即未初始化的变量。