机器数

一个数在计算机中的表示形式是二进制的话,这个数其实就叫机器数。机器数通常是带有符号的(指有正数和负数之分),计算机用最高位存放符号,这个 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的补码。