机器数
一个数在计算机中的表示形式是二进制的话,这个数其实就叫机器数。机器数通常是带有符号的(指有正数和负数之分),计算机用最高位存放符号,这个 bit 一般叫做符号位。 正数的符号位为 0, 负数的符号位为 1。
原码
十进制数据的二进制表现形式就是原码,原码最左边的一个数字就是符号位,0为正,1为负。
使用原码对正数进行计算不会有问题,例如:5 + 2
0 0 0 0 0 1 0 1
+ 0 0 1 0
-----------------
0 0 0 0 0 1 1 1
结果转成十进制刚好就等于 7,正确。
如果是负数的话,计算结果会出错,例如:-56 - 1
1 0 1 1 1 0 0 0
- 1
-----------------
1 0 1 1 0 1 1 1
结果转成十进制为-55,有误。
反码
正数的反码是其本身(等于原码),负数的反码是符号位保持不变,其余位取反。 反码的存在是为了正确计算负数,因为原码不能用于计算负数。
使用反码计算一下 -56 - 1:
1 1 0 0 0 1 1 1
- 1
-----------------
1 1 0 0 0 1 1 0
结果转为原码再转成二进制为-57,正确。
如果是负数跨零进行计算的话,计算得出的结果有误,例如:-3 + 5
1 1 1 1 1 1 0 0
+ 0 1 0 1
-----------------
0 0 0 0 0 0 0 1
把计算结果转成十进制就是1,有误。
补码
正数的补码是其本身,负数的补码等于其反码+1(符号位上的进位舍弃)。反码可以解决跨零计算的问题。
再来使用反码计算一下 -3 + 5 :
1 1 1 1 1 1 0 1
+ 0 1 0 1
-----------------
0 0 0 0 0 0 1 0
结果转成十进制刚好等于2,正确。
在计算机当中都是使用补码来进行计算和存储的。补码很好的解决了反码负数不能跨零计算的弊端,并且补码还可以记录一个特殊的值-128,这个数据在1个字节下是没有原码和反码的。
关于-128、+128、-0、+0
按照上述规定,1个字节能表示的反码范围为-127~127,而-128只有补码,这是为什么呢?
-0的原码是10000000,反码是11111111。假设-128也有原码反码,且原码是10000000,那么反码是11111111。可以发现,-128的反码和-0的反码相同,所以为了避免混淆,有了-0的原码,便不能有-128的原码补码,这是8位比特位(1个字节)位数限制决定的。
在1个字节下,原码和补码的表示范围都是-127~127,而补码的表示范围是-128~127。可以发现,补码比其它码多一位,这又是为什么呢?
可以知道,+0的原码和反码都是00000000,-0的原码是10000000,反码是11111111。而+0的补码是00000000,-0的补码是00000000,发现+0和-0的补码是一样的。即0的补码只有一种表示。
+128的原值在8位中是表达不出来的。那又该理解-128的补码是10000000呢?
我们将遵循这个计算法则:将负数取绝对值,再用二进制表示出这个绝对值 (不管符号位!),对该二进制数进行取反加一操作就得到负数的补码了。-128绝对值是128,不管符号位的二进制为10000000,取反加一为10000000,即为-128的补码。