目录
一、源码、反码、补码
(一)预备知识
认识二进制,十六进制,会二进制与十进制的相互转化运算。
由计算机的硬件决定,任何存储于计算机中的数据,其本质都是以二进制码存储。
根据冯~诺依曼提出的经典计算机体系结构框架。一台计算机由运算器,控制器,存储器,输入和输出设备组成。其中运算器,只有加法运算器,没有减法运算器(据说一开始是有的,后来由于减法器硬件开销太大,被废了 )
所以,计算机中的没法直接做减法的,它的减法是通过加法来实现的。你也许会说,现实世界中所有的减法也可以当成加法的,减去一个数,可以看作加上这个数的相反数。当然没错,但是前提是要先有负数的概念。这就为什么不得不引入一个该死的符号位。
而且从硬件的角度上看,只有正数加负数才算减法。 正数与正数相加,负数与负数相加,其实都可以通过加法器直接相加。
原码,反码,补码的产生过程,就是为了解决,计算机做减法和引入符号位(正号和负号)的问题。
(二)原码
原码:是最简单的机器数表示法。用最高位表示符号位,‘1’表示负号,‘0’表示正号。其他位存放该数的二进制的绝对值。
若以带符号位的四位二进值数为例:
1010 : 最高位为‘1’,表示这是一个负数,
其他三位为 '010', 即 (0*2^2) + (1*2^1) + (0*2^0) = 2("^"表示幂运算符),所以1010表示十进制数(-2)。
下图给出部份正负数的二进制原码表示法:
OK,原码表示法很简单有没有,虽然出现了 +0 和 -0,但是直观易懂。 于是,我们高兴的开始运算:
0001+0010=0011 (1 + 2 = 3) OK
0000+1000=1000 (+0 + (-0) = -0) 额,问题不大
0001+1001=1010 (1 + (-1) = -2)
噢,1+(-1)=-2
,这仿佛是在逗我呢。
于是我们可以看到其实正数之间的加法通常是不会出错的,因为它就是一个很简单的二进制加法。
而正数与负数相加,或负数与负数相加,就要引起莫名其妙的结果,这都是该死的符号位引起的。0分为+0
和-0
也是因他而起。
所以原码,虽然直观易懂,易于正值转换。但用来实现加减法的话,运算规则总归是太复杂。于是反码来了。
(三)反码
我们知道,原码最大的问题就在于一个数加上他的相反数不等于零。
例如:
0001+1001=1010 (1+(-1)=-2)
0010+1010=1100 (2+(-2)=-4)
于是反码的设计思想就是冲着解决这一点,既然一个负数是一个正数的相反数,那我们干脆用一个正数按位取反来表示负数试试。
反码:
正数的反码还是等于原码
负数的反码就是他的原码除符号位外,按位取反。
若以带符号位的四位二进制数为例: