判断运算是否越界,一定要在运算前判断。 不少同学误以为正数越界就一定是负数,并用这个性质判断是否越界。这是错误的。 举个例子,若整数最大 INT_MAX 按 2^31 算,也就是 2147483647 现在一个整数 1047483647 (把 INT_MAX 最高两位改成 10-) 如果把这个数 x10,当然越界 (因为最大整数是它的两倍不到)然而却会输出 1884901878 > 1047483647
为什么会这样呢?可以看看整型数据编码方式
对于整数来说,4个 byte 也就是32位,最高位是符号位,若为1时用补码表示负数。 如果是加法越界,常常出现进位使得最高位为 1,这样计算结果就成了负数(用补码表示) 但情况往往不是这样,比如这里的乘法。
1047483647 用二进制表示如下
0011 1110 0110 1111 0101 0100 1111 1111 x10 可以写为 x2+x8, 将二进制移位相加便是。
移1位(2倍):011 1110 0110 1111 0101 0100 1111 1111 0
移3位(8倍):1 1110 0110 1111 0101 0100 1111 1111 000
相加 (10倍): 0111 0000 0101 1001 0101 0001 1111 0110
最后结果最高位仍然是 0, 也就说仍然是整数,并且还比原数大
说了一堆就是想说明不能用正负性判断。
那该如何判断? 逆向先验证
//验证 a*10 会不会越界
if(INT_MAX/10 <a){
//会越界
}
其他方法以此类推