如何检查加法/减法是否产生溢出?

时间:2019-06-07 15:25:07

标签: c

所以我只是想将两个数字加在一起,

第一个是P1 = 2147483647,另一个是P2 = 1 这应该溢出int类型,所以我写这是为了防止计算机执行溢出

if((P1 + P2) > sizeof(int)){
    halt = 1; /*halt is just a flag*/
}

但是计算机显然仍然尝试对总和进行检查,这在我写的消息仅仅告诉我不能将这两个数字加在一起之前给了我一个运行时错误。我该怎么做而不会发生运行时错误,而只显示我的消息?

我也在尝试减法和乘法,但是问题是相同的。

编辑:我需要为一个项目执行此操作,我认为我无法使用库限制。h

2 个答案:

答案 0 :(得分:2)

#include <limits.h>
if (P2 > INT_MAX - P1) {
   printf("Overflow would occur\n");
}

说明:

INT_MAX - P1是可以添加到P1中而不会溢出的最大值。
如果P2大于该值,则该值太大,并且会发生溢出。


如果您还需要检查是否存在下溢,则数学思路是相同的:

if ( -P2 < P1 - INT_MIN) {
    printf("Underflow would occur\n");
} 

说明

(P1 - INT_MIN)是可以从P1中减去而不会下溢的最大*值。如果-P2的负数甚至更多,那么加法时将发生下溢。

*按大小而不是按值最大。

答案 1 :(得分:1)

测试溢出的经典技巧是计算:

if( (~(p1^p2) & (p1^(p1+p2)) & (1ull<<(8*sizeof(p1)-1)) ){
  printf("overflow in the addition of p1 and p2") ;
}

仅当两个数字具有相同的符号时才发生溢出的想法。在这种情况下,可以证明溢出将产生一个数字,其符号与自变量之一不同。那就是检查功能。
因此,在MSB(表达式的最后一部分)上,检查操作数的符号是​​否相同(表达式的第一部分),并且结果的符号是否与操作数1的符号(表达式的第二部分)不同。

对于减法,除去表达式中的位补码就足够了。