原码反码和补码
首先把方法放在前面:
再来看有趣的实验:
8位二进制所能表示的范围是多少呢?
让我们来看下(计算机中都是补码表示,所以下面的数字也都是补码)
从0000_0000到1111_1111,
其中0000_0000全零代表数字是零,
0000_0001到0111_1111因为首位是零,所以代表的是正整数,按普通方法求,+1到+127;
1000_0000到1111_1111因为首位是一,所以代表的是负整数,将所有位取反末尾加一得到的就是该负数的绝对值(0111_1111~0000_0000,再加1,1000_0000~0000_0001,表示128~1),-128到-1;
所以8位二进制可以表示的范围是-128~+127;
—-其中我们重点关注的是1000_0000代表的数字到底是多少,虽然利用方法求出了它是-128,同时我们可以进行验证一下:
因为1000_0000刚好是8位,占一个字节,而字符类型也是占一个字节,我们可以巧妙的用字符变量来存储,并将其以十进制来输出,从而验证我们的猜想。
做两个简单的实验吧:
1.
因为存储的是二进制的补码,首位是1,所以这个数是负整数,
将所有位取反,0000_0000…1010
再末位加一,0000_0000…1011
这个数是11,
所以原来的数应该是-11
2.
-3转成二进制补码,先求+3的二进制代码011,所有位取反100,末位加一得到101,不够位数左边补1,得到1111_1111_1111_1111_1111_1111_1111_1101,用16进制表示就是0xFFFFFFFD
我们再来做两个有趣的验证:关于溢出
第一个:
为何赋值128,输出却是-128的?
因为ch变量是字符型变量,在机器内部占一个字节(8位),而128是一个整型变量,占据4个字节,所以内部的补码应该是0000_0000_…1000_0000,
赋值运算直接将其截断,把1000_0000赋给了ch,而其补码代表的是-128,
所以输出结果是-128。
第二个:
同理129应该是0000_0000…1000_0001
将其截断赋给ch,
ch = 1000_0001,
这个补码表示的是-127