- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在阅读有关检测 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);
}
它说它不起作用,因为:
two’s-complement addition forms an abelian group, and so the expression (x+y)-x will evaluate to y regardless of whether or not the addition overflows, and that (x+y)-y will always evaluate to x
这到底是什么意思?这是否意味着C编译器替换sum
与 x+y
?
为了弄清楚它在说什么,我什至追踪了程序的汇编代码,但没有替换的迹象。
更新:我的问题的本质是,GCC 是否会评估表达式而不计算它?
这不是关于补码的问题。
您可以在here中看到示例输出。 .
最佳答案
如果您举一个 4 (0b0100) + 5 (0b0101)
的简单示例,您会发现无符号总和应为 9 (1001)
,实际上是 -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 代码,但仍然导致溢出。
摘自维基百科关于 two's complement 的文章:
Two's complement Decimal0111 70110 60101 50100 40011 30010 20001 10000 01111 −11110 −21101 −31100 −41011 −51010 −61001 −71000 −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 中的大数加法结果(阿贝尔群),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11476410/
我是一名优秀的程序员,十分优秀!