有(一):
// 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;
哪个是首选或有更好的方法。
有(一):
// 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;
哪个是首选或有更好的方法。
整数溢出是 C 中“未定义行为”的典型示例(注意对无符号整数的操作永远不会溢出,它们被定义为回绕)。这意味着一旦你执行了x + y
,如果它溢出,你就已经被水洗了。做任何检查都太晚了——你的程序可能已经崩溃了。把它想象成检查除以零 - 如果你等到执行除法之后再检查,那已经太晚了。
所以这意味着方法(1)是唯一正确的方法。对于max
,您可以使用INT_MAX
from <limits.h>
。
如果x
和/或y
可以为负数,那么事情就更难了——您需要以测试本身不会导致溢出的方式进行测试。
if ((y > 0 && x > INT_MAX - y) ||
(y < 0 && x < INT_MIN - y))
{
/* Oh no, overflow */
}
else
{
sum = x + y;
}
您实际上只能检查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 */
}
这不适用于使用任何饱和算法的机器
您只需检查其中之一。如果 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;
}