在CPython的源码中,进行有符号整数的加法时,会进行溢出判断,以决定是否使用long型来存放结果,判断条件如下:
int a, b, i;
i = a + b;
if ((i ^ a) < 0 && (i ^ b) < 0)
printf("overflow\n");
从上面可见(i ^ a) < 0 && (i ^ b) < 0是判断溢出的关键条件,接下来我们验证这个方法的有效性:
1. 我们知道有符号整数进行相加是存在溢出可能的,大于最大值(以4字节为例,即为2147483647)即为上溢,小于最小值(-2147483648)即为下溢
2. 可想而知,如果要上溢,那么势必需要两个正整数相加才会出现;而下溢则需要两个负整数相加才会出现
a. 两个正整数相加如果溢出了,那么第一个bit即符号位必为1, 也就是说和为负数,负数和正数的按位异或结果必然也为负数;如果没有溢出,那么和为正数,正数和正数的按位异或必为正数
b. 两个负整数相加如果溢出了,那么第一个bit即符号位必为0,也就是说和为正数,同样正数和负数的按位异或必然也为负数;如果没有溢出,那么和为负数,负数和负数的按位异或必为正数
c. 一正一负两个整数相加必然不会溢出,结果可正可负,与2个加数分别进行按位异或操作至少有一个正数
综上所述,两个有符号整数(长整数)进行加法,所得之和与2个加数分别进行按位异或操作,如果2个结果均为负数,那么发生了溢出;反之则没有