private int add(int x, int y)
{
      return ((x&0x7FFFFFFF) + (y&0x7FFFFFFF)) ^ (x&0x80000000) ^ (y&0x80000000);
}
以上代码实现两个数相加,注释说明是为防相加后溢出。
请高手解释这行代码防溢出的原理。

解决方案 »

  1.   

    加完后又放在了int中,这也能防止溢出?
      

  2.   

    http://wenwen.soso.com/z/q344721665.htm
      

  3.   

    http://wenwen.soso.com/z/q344721665.htm
      

  4.   

    把最高位和非最高位的加法分割开。& 0x7FFFFFFF 是 与 0111 111 ... 111 位乘运算。 把最高位变成0。这样
    ((x&0x7FFFFFFF) + (y&0x7FFFFFFF)) 是去掉最高位的加法, 最高位是两个一定是0,相加不会溢出。
    & 0x80000000 是 与 1000...000 位乘运算,取最高位。计算最高位加法时,溢出时进位去掉, 0+0=1+1=0 0+1=1+0=1 正好是异或运算。
    所以上面三个数做xor:((x&0x7FFFFFFF) + (y&0x7FFFFFFF)) ^ (x&0x80000000) ^ (y&0x80000000);
      

  5.   

    首先来看看二进制的相加
    二进制 1+1=(1)0 考虑溢出,高位的1被溢出,只留下低位的0
    二进制 1+0=1 没有发生溢出
    二进制 0+0=0 没有发生溢出再看二进制的异或
    二进制 1^1=0 没有发生溢出
    二进制 1^0=1
    二进制 0^0=0所以
    二进制 1+1=(1)0=1^1 考虑溢出
    二进制 1+0=1=1^1
    二进制 0+0=0=0^0
    即加法和异或在发生溢出的时候是等效的,所以可以用异或来避免溢出一个数x可以写成二进制的相加
    x = x&0x80000000 + x&0x7FFFFFFF (高1位 + 低31位)
      = x&0x80000000 ^ x&0x7FFFFFFF (可以改成异或 高1位跟0异或,低31位跟0异或)所以两个数相加 (把个别加法改成异或)
    x + y = (x&0x7FFFFFFF + x&0x80000000) + (y&0x7FFFFFFF + y&0x80000000)
          = (x&0x7FFFFFFF + y&0x7FFFFFFF) + (x&0x80000000 + y&0x80000000)
          = (x&0x7FFFFFFF + y&0x7FFFFFFF) ^ (x&0x80000000 + y&0x80000000)
          = (x&0x7FFFFFFF + y&0x7FFFFFFF) ^ (x&0x80000000 ^ y&0x80000000)
          = (x&0x7FFFFFFF + y&0x7FFFFFFF) ^ x&0x80000000 ^ y&0x80000000