C 中整数溢出的意外结果
使用整数类型时,了解溢出的含义至关重要。在这篇文章中,我们将探讨为什么有符号和无符号整数溢出会在 C 程序中产生意外结果。
考虑以下测试整数溢出的程序:
#include <iostream> int main() { int x(0); std::cout << x << std::endl; x = x + 2147483647; std::cout << x << std::endl; x = x + 1; std::cout << x << std::endl; std::cout << std::endl; unsigned int y(0); std::cout << y << std::endl; y = y + 4294967295; std::cout << y << std::endl; y = y + 1; std::cout << y << std::endl; }
输出令人惊讶:
0 2147483647 -2147483648 0 4294967295 0
有符号整数溢出
有符号整数溢出是未定义的行为。这意味着编译器可以做任何它想做的事情,包括产生像本例一样的错误结果。
无符号整数溢出
相比之下,无符号整数溢出很好-定义。该值环绕,类似于除以 2^bits 的模数(其中,bits 是数据类型中的位数)。由于我们有一个 32 位 int:
4294967295 + 1 = 4294967296 % 2^32 = 0
具体实现细节
尽管有符号整数溢出是未定义的行为,但大多数实现都使用 2 的补码表示。这解释了在该程序中观察到的具体结果:
加 1 时POS_MAX:
0111 + 1 = 1000
由于设置了前导位,因此它是一个负数。为了找到实际值,我们执行 2 的补码逆:
1000 - 1 = 0111 ~0111 = 1000 = -8
因此,最终值为 -8,出现在程序的输出中。
以上是为什么整数溢出会在 C 中产生意外结果?的详细内容。更多信息请关注PHP中文网其他相关文章!