如何检查C中的整数溢出?
可能重复:
在C / C ++中检测整数溢出的最佳方法
有(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;
哪个是首选或有更好的方法。
整数溢出是C中“未定义行为”的规范示例(注意无符号整数上的操作永远不会溢出,而是定义为环绕式转换)。 这意味着一旦你执行了x + y
,如果它已经溢出,你就已经被软管了。 做任何检查都为时已晚 – 您的程序可能已经崩溃了。 可以把它想象为检查除零 – 如果你等到除法执行后再检查,那已经太晚了。
所以这意味着方法(1)是唯一正确的方法。 对于max
,您可以使用INT_MAX
。
如果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; }