28

有(一):

// 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;

哪个是首选或有更好的方法。

4

3 回答 3

62

整数溢出是 C 中“未定义行为”的典型示例(注意对无符号整数的操作永远不会溢出,它们被定义为回绕)。这意味着一旦你执行了x + y,如果它溢出,你就已经被水洗了。做任何检查都太晚了——你的程序可能已经崩溃了。把它想象成检查除以零 - 如果你等到执行除法之后再检查,那已经太晚了。

所以这意味着方法(1)是唯一正确的方法。对于max,您可以使用INT_MAXfrom <limits.h>

如果x和/或y可以为负数,那么事情就更难了——您需要以测试本身不会导致溢出的方式进行测试。

if ((y > 0 && x > INT_MAX - y) ||
    (y < 0 && x < INT_MIN - y))
{
    /* Oh no, overflow */
}
else
{
    sum = x + y;
}
于 2010-04-13T23:34:56.897 回答
7

您实际上只能检查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 */
}

这不适用于使用任何饱和算法的机器

于 2010-04-13T22:48:49.693 回答
-6

您只需检查其中之一。如果 x + y 溢出,它将小于 x 和 y。因此:

int sum = x + y;
if (sum < x) error;

应该足够了。

以下站点有一堆关于整数溢出的内容:

http://www.fefe.de/intof.html

如果要处理负数,可以扩展:

int sum = x + y;
if (y >= 0) {
   if (sum < x) error;
} else {
   if (sum > x) error;
}
于 2010-04-13T22:36:55.003 回答