C/C++中整数加法/减法的溢出问题

    C/C++中的整数类型有short、int、long等,这些整数类型均为有符号整型,即二进制最高位位符号位,相应的无符号整型只需要在各类型前面加上unsigned,如unsigned int等。现在有如下程序,其输出结果会是多少呢?

short x = 0x7fff;  //最大的有符号整数
short y = x + 2;   //溢出
short z = y - 2;   //溢出
unsigned short a = 0xffff; //最大的无符号整数
unsigned short b = a + 2; //溢出
unsigned short c = b - 2; //溢出
cout<<"y="<<y<<endl;
cout<<"z="<<z<<endl;
cout<<"b="<<b<<endl;
cout<<"c="<<c<<endl;

    输出结果如下:

x=32767
y=-32767
z=32767
b=1
c=65535

    现在来分析上述结果,首先明确对于短整型short而言,长度为2字节,即16位。那么有符号位时其最小为-2^15,最大为 2^15-1, 而无符号位时,最小为0,最大为2^16-1。
    由于x+2的结果超出了所能表示的最大整数,因此他输出了-32767,我们可以这样来理解,因为计算机中的加法是通过补码来实现的,x的补码是0x7fff(正数的补码等于原码),2的补码等于(0x0002),所以y=x+2=0x8001,这说明y的补码是一个符号位为1,其余各位均为0的补码,其实它就是0xffff=-32767的补码。同理z=y-2=0x7fff,它是32767的补码。
    由于b=a+2=0xffff+0x0002=0x0001=1,所以其结果为1;而c=b-2=0x0001-0x0002=-1,因为-1的补码是0xffff,而无符号整数没有符号位,那么-1的补码就等于c的原码,所以c=0xffff。
    简言之,对于有符号整型相加时,若溢出,如0x7ff9+8=-2^15+1, 0x7ffe+6=-2^15+5 ;相减时,若溢出,如-32766-5=32767-2。
    同理,对于无符号整型相加时,若溢出,如0xffff+2=0+1;相减时,若溢出,如0-2=0xffff-1;

你可能感兴趣的:(C/C++)