假设 a=1
1+(-1) =0
但使用 4 位二进制,使用 2 的补码
0001+1111=10000 ~ 0000
有符号整数溢出不是未定义的行为吗?
对于这种微不足道的结果,我们是否依赖于未定义的行为,或者我错过了什么。
来自 wikipedia:如果左边的两个进位位(这些示例中顶行最左边的位)都是 1 或都是 0,则结果有效;如果左两个进位位是“1 0”或“0 1”,则发生符号溢出。
假设 a=1
1+(-1) =0
但使用 4 位二进制,使用 2 的补码
0001+1111=10000 ~ 0000
有符号整数溢出不是未定义的行为吗?
对于这种微不足道的结果,我们是否依赖于未定义的行为,或者我错过了什么。
来自 wikipedia:如果左边的两个进位位(这些示例中顶行最左边的位)都是 1 或都是 0,则结果有效;如果左两个进位位是“1 0”或“0 1”,则发生符号溢出。
添加带有相反符号的有符号数字永远不会产生溢出。实际上,硬件通常有两个与加法相关的标志位,即溢出位和进位位。
仅当容器不够大而无法正确表示数字时,才会设置溢出位。对于有符号数,硬件在分析每个操作数的符号位和结果的符号后设置该位。如果操作数的符号不同,则永远不会设置该位。否则,如果操作数的信号相等,则分析结果的符号。如果与操作数不同,则设置该标志,表示结果溢出。
在您的示例中,每个操作数的符号不同,因此没有溢出,但是如果您想使用大容器来保持操作正确,则此操作会生成一个进位位。
有符号整数溢出是未定义的,但我看不出这将是一个问题,因为您要添加两个有符号数字并且结果确实在范围内。
对于 4 位整数类型,溢出将添加 7+7,其中结果应为 14,不适合 -2^3..2^3-1 范围
底层表示可能在内部使用溢出来获得正确的结果,但这无关紧要。仅当操作的结果超出类型的范围时,行为才被定义。
这是未定义的行为,但我不确定我是否理解您的问题。您是在问为什么它在该示例中有效?因为这些值在范围内,结果也在范围内。考虑
-8 + -1
在 4 位
1000 + 1111 -> 10111 -> 0111 -> 7. 这里我们不再有正确答案