如何检查是否发生溢出?

时间:2011-10-07 06:19:34

标签: c overflow

  

可能重复:
  Best way to detect integer overflow in C/C++

这可能是一个新手问题,但我如何检查一些溢出会影响我在C中的数字的值。例如,当乘以整数,并等待整数结果时,如果实际结果大于最大整数值,实际结果改变了(对吗?)。那么如何判断出这样的事情呢?

7 个答案:

答案 0 :(得分:4)

C99标准的这一部分解释了未定义的行为:

  

<强> 3.4.3
  未定义的行为
  在使用不可移植或错误的程序结构或错误数据时,   本国际标准没有要求   注意可能的未定义行为包括完全忽略不可预测的情况   结果,在翻译或程序执行过程中以文件化的方式表现   环境(有或没有发出诊断信息),终止翻译或   执行(发出诊断信息)   示例
  未定义行为的一个示例是整数溢出的行为

所以你几乎没有运气,事实上,在一般情况下,没有便携的方法可以检测到这种情况。
您的编译器/实现可能具有扩展/支持,并且有一些技术可以避免这些情况 请参阅此问题以获得出色的建议:Best way to detect integer overflow in C/C++

答案 1 :(得分:4)

有符号整数溢出就像被零除 - 它会导致未定义的行为,所以你必须检查它是否会在执行潜在溢出操作之前发生。一旦你满溢,所有的赌注都会被取消 - 你的代码可以做任何事情。

*_MAX中定义的_MIN<limits.h>宏可以派上用场,但是您需要注意不要在测试中调用未定义的行为。例如,要检查给定a * b int a, b;是否会溢出,您可以使用:

if ((b > 0 && a <= INT_MAX / b && a >= INT_MIN / b) ||
    (b == 0) ||
    (b == -1 && a >= -INT_MAX) ||
    (b < -1 && a >= INT_MAX / b && a <= INT_MIN / b))
{
    result = a * b;
}
else
{
    /* calculation would overflow */
}

(请注意,这避免了一个微妙的缺陷,就是你无法计算INT_MIN / -1 - 这样的数字不能保证可以表示,并且确实会在公共平台上造成致命的陷阱。)

答案 2 :(得分:1)

如果结果数小于其中一个输入。

a + b = c,如果c < a =&gt;溢出。 编辑:要快,这只适用于无符号整数的加法。

答案 3 :(得分:1)

如果您在编程时表示意思,则可以调试代码。

如果您的意思是在运行时,您可以添加一些条件,如果超出限制,请执行某些操作。

当计算的收益率超出范围时,C不知道该怎么做。你必须通过测试操作数来避免这种情况。

答案 4 :(得分:1)

检查http://www.fefe.de/intof.html。它向您展示了如何检查实际结果是否大于最大整数值。

答案 5 :(得分:1)

在一般情况下,你只能通过盯着结果来知道是否发生了溢出。但是,您可以做的是检查操作是否会单独溢出。例如。如果你想检查a * b是否溢出,其中a和b是int,你需要解决不等式

a * b <= INT_MAX

也就是说,如果一个&lt; = INT_MAX / b,则乘法会溢出。

答案 6 :(得分:0)

只要您使用无符号整数进行算术运算,或者可以依赖于有关签名整数溢出行为的特定于实现的保证,您可以使用各种技巧。

在无符号乘法的情况下,最简单的是:

unsigned int lhs = something, rhs = something_else;
unsigned int product = lhs * rhs;

if (lhs != 0 && product/lhs != rhs) { overflow occurred }

它不太可能快,但它是便携式的。添加的无符号溢出检查也很简单 - 选择其中一个操作数,然后当且仅当总和小于该值时才发生溢出。