5

可能重复:
在 C/C++ 中检测整数溢出的最佳方法

我正在用 C 编写一个函数,但问题是通用的。该函数接受三个整数并返回有关这三个整数的一些信息。

我怀疑这里的问题是整数可以达到最大值,这可能导致溢出。

例如:如果我将 a 作为最大值传递,并且 b 可以是 1 - max,那么在这种情况下,if 条件中的表达式 (a+b)>c 会导致溢出吗?如果是这样,我该如何处理?

我的解决方案是保留一个长整数作为临时变量以保留 a+b 的值并在表达式中使用它,但这听起来很脏。

参考这个片段:

int
triangle_type(int a, int b, int c) {
    if (!((a+b)>c)&&((b+c) > a)&&((a+c>b))) {
        return -1;
    }
}
4

2 回答 2

3

在当前的处理器上,整数没有真正的信号溢出。因此,在 32 位处理器上,整数运算在位级别完成模 2^32。当您将两个int-s 相加并发生一些“溢出”时,会在某个状态寄存器中设置一个溢出(或进位)位(并且算术运算完成模数 2^32)。如果(通常情况下)没有机器指令测试溢出状态位,则不会发生任何事情。

所以控制流不会因为溢出而改变(它通常会在除以零时改变,例如使用 SIGEMT 信号)。

如果您想在 C 中便携式捕获溢出情况,您可以测试例如两个正int-s 的总和是否保持正数。(如果它是负数,则确实发生了溢出)。

您也可能对bignums感兴趣,例如使用gmp 库。您还可以<stdint.h>谨慎使用和使用int32_tint64_t式强制转换。最后,你可以(就像大多数程序员一样)选择忽略这个问题。

注意:正如 Jonathan 所注意到的,您可能会陷入未定义行为或未指定行为的情况。如果您真的在乎,请使用 bignums。但是,您可以选择根本不关心。

于 2012-10-20T05:51:01.420 回答
0

你可以做这样的事情

// returns true if a+b > c
inline int safe_sum_greater (int a, int b, int c) {
   int a1 = a / 4; int a2 = a % 4;
   int b1 = b / 4; int b2 = b % 4;
   int c1 = c / 4; int c2 = c % 4;
   int s2 = a2 + b2;

   int s1 = a1 + b1 + s2 / 4;
   s2 = s2 % 4;
   return (s1 > c1) || ( (s1 == c1) && (s2 > c2) );
}

性能不会很差,因为只会使用按位操作。对于负数,我没有广泛考虑这一点,因此请谨慎使用。

于 2012-10-20T06:42:52.580 回答