c++ int 负数 补码 隐式类型转换
unsigned y = 1; int x = -2; cout << x + y << endl;
对于上述的结果为
这里面有一个负数的补码问题和不同类型之间的隐式类型转换问题
首先负数的表示方法是负数的绝对值的二进制码取反再加1,-2的补码计算就是:
0000 0000 0000 0010->1111 1111 1111 1101->1111 1111 1111 1111 1110
而整数的加减在内部都是通过加运算实现的,主要原因是使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。
1的二进制表示是:0000 0000 0000 0001
x + y在内部的二进制表示就是1111 1111 1111 1111
对于最后的类型又有一个隐式类型转换的规则,两个通用的指导原则如下:
1、为防止精度损失,如果必要的话,类型总是被提升为较宽的类型。
2、所有含有小于整形的有序类型的算术表达式在计算之前其类型都会被转换成整形。
一般来说各种类型的转换顺序为 long double > double > float >= int >= short > char,unsigned > signed 。
由于unsigned > signed,所以x+y被解释为unsigned,最后输出值就是2的32次方减一
int取值范围
-2^31 ~ 2^31-1
为什么负数是 -2^31 而不是-2^31-1呢?
因为规定了1000 0000, 0000 0000, 0000 0000, 0000 0000这个特殊的数(本来是-0的)为-2^31,所以负数就多一个
同理char类型的取值范围为-128到127,在这里也是把1000 0000表示为-128