一种swap_int()写法会不会因为溢出导致出错?

这个样子:

void swap_int(int *a, int *b){
    *a = *a + *b;
    *b = *a - *b;
    *a = *a - *b;
}

当a+b超出int(signed)可表示范围,溢出,交换时会不会出错?

VS2013 && MinGW.org GCC-6.3.0-1编译器测试:

当a=0x7FFFFFFF(INT_MAX),b=0x7FFFFFFE时,相加会溢出,但是结果显示正确。为什么呢?

我们试试0x7FFFFFFF+1,结果为-2147483648,即负数最小值;+2得-2147483647;INT_MAX*2得-2;INT_MIN*2得0。可以找出规律(至少在vs和gcc下是这样):

当产生溢出时,结果会以如下图所示规律出现:

即INX_MAX+1=INX_MIN,INT_MIN-1=INT_MAX。

再看到上述交换函数,当a+b会产生溢出时,则a,b必同时在[INT_MAX/2,INT_MAX]或同时在[INT_MIN,INT_MIN/2]。

即a+b的值即使溢出也不会超出0,若a=INT_MAX,b=2,则a=a+b=INT_MIN+1(从上图最低端向左走),b=a-b=INT_MIN+1+(-b)=INT_MAX,两个负数相加,再次溢出(从上图最低端向右走),a=a-b=INT_MIN+1+(-INX_MAX)=2。

因此即使相加结果溢出也不会影响交换结果。

猜你喜欢

转载自www.cnblogs.com/dabai56/p/10994770.html