It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center。
7年前关闭。
我正在阅读有关检测C中溢出的技术。另外一个显示错误检测溢出的解决方案的示例之一是:
它说它不起作用,因为:
二的补码加法组成一个阿贝尔群,所以
表达式(x + y)-x的计算结果为y,无论是否
加法运算溢出,并且(x + y)-y始终取值为x
这到底是什么意思?这是否意味着C编译器将
为了弄清楚是什么,我什至跟踪了程序的汇编代码,但是没有替换的迹象。
更新:我的问题的实质是,GCC是否在不计算表达式的情况下评估表达式?
这不是关于二进制补码的问题。
您可以在here中看到示例输出。
您最终得到0101,它是5(在2的补码运算中丢弃了溢出的最高有效1)。从总和中减去5等于4:
这满足您提供的c代码,但仍然导致溢出。
摘自Wikipedia关于two's complement的文章:
就像上面的示例一样,减去
7年前关闭。
我正在阅读有关检测C中溢出的技术。另外一个显示错误检测溢出的解决方案的示例之一是:
/* Determine whether arguments can be added without overflow */
int tadd_ok(int x, int y) {
int sum = x+y;
return (sum-x == y) && (sum-y == x);
}
它说它不起作用,因为:
二的补码加法组成一个阿贝尔群,所以
表达式(x + y)-x的计算结果为y,无论是否
加法运算溢出,并且(x + y)-y始终取值为x
这到底是什么意思?这是否意味着C编译器将
sum
替换为x+y
?为了弄清楚是什么,我什至跟踪了程序的汇编代码,但是没有替换的迹象。
更新:我的问题的实质是,GCC是否在不计算表达式的情况下评估表达式?
这不是关于二进制补码的问题。
您可以在here中看到示例输出。
最佳答案
如果您以4 (0b0100) + 5 (0b0101)
的小例子为例,则可以看到无符号和应为9 (1001)
,实际上是2的补码中的-7
。如果然后取该和(0b1001)并使用二进制补码算术从中减去4:
0b1001 - 0b0100 = 0b1001 + 2s_complement(0b0100) = 0b1001 + 0b1100 = 0b1_0101
您最终得到0101,它是5(在2的补码运算中丢弃了溢出的最高有效1)。从总和中减去5等于4:
0b1001 - 0b0101 = 0b1001 + 2s_complement(0b0101) = 0b1001 + 0b1011 = 0b1_0100
这满足您提供的c代码,但仍然导致溢出。
摘自Wikipedia关于two's complement的文章:
Two's complement Decimal 0111 7 0110 6 0101 5 0100 4 0011 3 0010 2 0001 1 0000 0 1111 −1 1110 −2 1101 −3 1100 −4 1011 −5 1010 −6 1001 −7 1000 −8
Update:
To demonstrate your INT_MAX example using my trivial 4 bit integer system with INT_MAX = 7 we can see the same result as your c code.
7 + 7 (0b0111 + 0b0111) = 0b1110 (-2 in two's complement)
就像上面的示例一样,减去
sum - 7
等于7
。 0b1110 - 0b0111 = 0b1110 + 2s_complement(0b0111) = 0b1110 + 0b1001 = 0b1_0111
关于c - Gcc(Abelian group)中大数的加法结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11476410/
10-12 16:13