Gan*_*ker 26 c integer-overflow
有(1):
// assume x,y are non-negative
if(x > max - y) error;
Run Code Online (Sandbox Code Playgroud)
并且(2):
// assume x,y are non-negative
int sum = x + y;
if(sum < x || sum < y) error;
Run Code Online (Sandbox Code Playgroud)
哪个是首选或有更好的方法.
caf*_*caf 60
整数溢出是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;
}
Run Code Online (Sandbox Code Playgroud)
你真的只能用unsigned
整数和算术来检查溢出:
unsigned a,b,c;
a = b + c;
if (a < b) {
/* overflow */
}
Run Code Online (Sandbox Code Playgroud)
带有符号整数的溢出行为在C中是未定义的,但在大多数机器上都可以使用
int a,b,c;
a = b + c;
if (c < 0 ? a > b : a < b) {
/* overflow */
}
Run Code Online (Sandbox Code Playgroud)
这不适用于使用任何饱和算法的机器
cla*_*hey -6
您只需检查其中一项即可。如果 x + y 溢出,它将小于 x 和 y。因此:
int sum = x + y;
if (sum < x) error;
Run Code Online (Sandbox Code Playgroud)
应该足够了。
以下站点有很多关于整数溢出的内容:
如果要处理负数,可以扩展:
int sum = x + y;
if (y >= 0) {
if (sum < x) error;
} else {
if (sum > x) error;
}
Run Code Online (Sandbox Code Playgroud)