我正在用 C++ 编写一个程序来查找 ab = c 的所有解,其中 < em>a、b 和 c 一起使用所有数字 0-9 一次。该程序循环遍历 a 和 b 的值,并且每次对 a、b 运行数字计数例程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_MIN
或 INT_MAX
。
关于c++ - 如何检测无符号整数溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41597229/