因为以前上学期间一直对原码、反码、补码的问题比较困惑,就是干什么弄一些反码、补码的概念,直接用首位符号位+数值表示就行了。
首先我以8位bit表示一个整数为例:
第一步:我们用8位来表示,当然脑子里面首先想到的是能表示多少数值,按每位有两种可能(0、1),知道可以表示8个2相乘的整数,也就是2的8次方,范围在0-255。
第二步:我们想到了表示的范围,即0-(2的8次方-1),但是有个疑问就出来了,负数呢,比如-1 - (-256)怎么表示,然后你就会想到用首位当住符号位,后面7位表示数值,范围在0-127(2的7次方-1)和-1-(-128)(-128用1000 0000表示),一共表示256(2的8次方)个整数值。
第三步:为什么不用如上负数的表示方式,后来经我自己在网上的查询,主要是由于这种方式,即不能正常的完成加法规则运算,举例:
10+(-8)=
0000 1010
+ 1000 1000
----------------------
1001 0010
根据如上计算得出 -18,得出的结果并不是我们理想中的值,对于计算机来说,也不能按原来对应位相加的方式来计算,需要区别处理,而算法运算需要CPU中对应电路模块去处理,这样就要增加电路模块,能不能把负数转换成按某种规则的表示方式,以便使它适应现有的加法运算方式,显然是可以的。
第四步:引入模的概念,即范围,就是一个容器里面能存放的东西是额定的 ,比如时钟1-12,如当前时针在10点,我们需要调整到2点,可以回调8小时,或则向前调整4(12-8)小时,即10+4 =14,但是容器最大位12,所以要进行截取14-12=2。同理,8位字节码只能表示2的8次方个数据,即最大值256。
第五步:根据第四步的原理,10-8,能不能表示成10+?,即10-8 = 10+?,那么?= N(2^8,8),这个公式的含义就是由2^8和8得到,根据第四步向前调整的方式 ?=2^8-8,即 10-8 = 10+(2^8-8)。
第六步:(2^8-8) = (2^8-1)+1-8 = (2^8-1) -8 +1 ,而(2^8-1) -8等于:
1111 1111 =2^8-1
- 0000 1000 =8
-------------------------
1111 01111 = 8取反
实际上就是8取反的操作,然后再加1,这就是我们所说的正数取反+1,从模的角度来说,它是对负数进行的等价转换,这样计算机就可以直接拿它参与加法运算,从而得到
等价减法的目的,而我们把这种转换后得数据叫做补码。这大概是反码和补码引入的原因。