在功能检查中如何处理加法中的整数溢出?

Gau*_*nha 5 c c++

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

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

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

例如:如果我尽可能传递a且b可以是1-max,那么在这种情况下,如果条件导致溢出,表达式(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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Bas*_*tch 3

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

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

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

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

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

  • 如果溢出有符号算术,则行为是未定义的。任何事情都可能发生——而且可能会以 2^32 为模进行环绕。但是,由于它在形式上是未定义的,如果编译器可以发现它会发生,它可以完全消除该表达式。2011 年或 2012 年,comp.lang.c 或 comp.lang.c.moderated 新闻组对此进行了广泛讨论。不要沉溺于未定义的行为;编译器没有义务警告您它将执行未定义的操作。它可以在您当前的机器上使用当前的编译器运行;它可能随时停止工作。 (6认同)