gpt4 book ai didi

c - Gcc 中的大数加法结果(阿贝尔群)

转载 作者:行者123 更新时间:2023-11-30 14:24:40 24 4
gpt4 key购买 nike

我正在阅读有关检测 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编译器替换sumx+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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com