有(1):
// assume x,y are non-negative
if(x > max - y) error;
和(2):
// assume x,y are non-negative
int sum = x + y;
if(sum < x || sum < y) error;
哪个是首选或有更好的方法。
答案 0 :(得分:58)
整数溢出是C中“未定义行为”的规范示例(注意无符号整数上的操作永远不会溢出,而是定义为环绕转换)。这意味着一旦你执行了x + y
,如果它已经溢出,你就已经被强行了。做任何检查都为时已晚 - 您的程序可能已经崩溃了。可以把它想象为检查除零 - 如果你等到除法执行后再检查,那已经太晚了。
所以这意味着方法(1)是唯一正确的方法。对于max
,您可以使用INT_MAX
中的<limits.h>
。
如果x
和/或y
可能是否定的,那么事情就更难了 - 您需要以测试本身不会导致溢出的方式进行测试。
if ((y > 0 && x > INT_MAX - y) ||
(y < 0 && x < INT_MIN - y))
{
/* Oh no, overflow */
}
else
{
sum = x + y;
}
答案 1 :(得分:6)
您实际上只能通过unsigned
整数和算术检查溢出:
unsigned a,b,c;
a = b + c;
if (a < b) {
/* overflow */
}
在C中未定义带有符号整数的溢出行为,但在大多数机器上都可以使用
int a,b,c;
a = b + c;
if (c < 0 ? a > b : a < b) {
/* overflow */
}
这不适用于使用任何类型的饱和算法的机器
答案 2 :(得分:-5)
您只需要检查其中一个。如果x + y溢出,它将小于x和y。因此:
int sum = x + y;
if (sum < x) error;
应该足够了。
以下网站有很多关于整数溢出的内容:
如果您想处理负数,可以进行扩展:
int sum = x + y;
if (y >= 0) {
if (sum < x) error;
} else {
if (sum > x) error;
}