c++ - 如何检测无符号整数溢出?

标签 c++ c integer-overflow

我正在用 C++ 编写一个程序来查找 ab = c 的所有解,其中 < em>a、bc 一起使用所有数字 0-9 一次。该程序循环遍历 ab 的值,并且每次对 ab 运行数字计数例程em> 和 ab 检查数字条件是否满足。

但是,当ab溢出整数限制时,可能会生成虚假解。我最终使用如下代码检查了这一点:

unsigned long b, c, c_test;
...
c_test=c*b;         // Possible overflow
if (c_test/b != c) {/* There has been an overflow*/}
else c=c_test;      // No overflow

是否有更好的方法来测试溢出?我知道有些芯片有一个内部标志,当发生溢出时会设置该标志,但我从未见过它通过 C 或 C++ 访问。

<小时/>

请注意,signed int 溢出是 C 和 C++ 中未定义的行为,因此您必须检测它而不是实际导致它。对于加法之前的有符号 int 溢出,请参阅 Detecting signed overflow in C/C++

最佳答案

我发现您正在使用无符号整数。根据定义,在 C 中(我不了解 C++),无符号算术不会溢出...所以,至少对于 C,你的观点没有实际意义:)

对于有符号整数,一旦出现溢出,undefined behaviour (UB) 已经发生,并且您的程序可以执行任何操作(例如:渲染测试不确定)。

#include <limits.h>

int a = <something>;
int x = <something>;
a += x;              /* UB */
if (a < 0) {         /* Unreliable test */
  /* ... */
}

要创建符合要求的程序,您需要在生成所述溢出之前测试溢出。该方法也可以用于无符号整数:

// For addition
#include <limits.h>

int a = <something>;
int x = <something>;
if (x > 0 && a > INT_MAX - x) // `a + x` would overflow
if (x < 0 && a < INT_MIN - x) // `a + x` would underflow
<小时/>
// For subtraction
#include <limits.h>
int a = <something>;
int x = <something>;
if (x < 0 && a > INT_MAX + x) // `a - x` would overflow
if (x > 0 && a < INT_MIN + x) // `a - x` would underflow
<小时/>
// For multiplication
#include <limits.h>

int a = <something>;
int x = <something>;
// There may be a need to check for -1 for two's complement machines.
// If one number is -1 and another is INT_MIN, multiplying them we get abs(INT_MIN) which is 1 higher than INT_MAX
if (a == -1 && x == INT_MIN) // `a * x` can overflow
if (x == -1 && a == INT_MIN) // `a * x` (or `a / x`) can overflow
// general case
if (x != 0 && a > INT_MAX / x) // `a * x` would overflow
if (x != 0 && a < INT_MIN / x) // `a * x` would underflow
<小时/>

对于除法(INT_MIN-1 特殊情况除外),不可能超过 INT_MININT_MAX

关于c++ - 如何检测无符号整数溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41597229/

相关文章:

c++ - 为什么将返回指针指向原始类的奇怪行为?

c++ - Doxygen 未记录的字符串值

c++ - 如何使用带有右值引用参数的初始化程序//为什么不能用另一个 C 样式数组变量初始化 C 样式数组

ios - 快速更改 .h View Controller 文件中的变量

c++11 - 基于 C++ 中可能输入的最大范围推导返回类型

c++ - gcc 过度对齐的新支持 (alignas)

c++ - 是否可以通过溢出 C 中的第一个元素来写入数组的第二个元素?

c - 使用结构时使用未声明的标识符?

c - 相同值的不同 Int 值?

database - 如何处理压缩十进制字段上的 AS400 DB2 数据溢出?