机器数
数字,一般来说,是指纸面上写的阿拉伯数字:0、1、2、3 ... 9。
在钟表的表面上,也常见罗马数字:I、II、III、IV ... 。
此外,在支票上,还有中文数字:零、壹、贰、叁 ... 玖。
在计算机里面,是用电压信号表示数字的。
由于在现代计算机中,只使用高低两种电平,所以,计算机中的数,也只有两种。
即:高电平(3.2~5.0V)作为 1,低电平(0~0.3V)记为 0。这就构成了二进制数。
(曾经有过 “模拟式计算机”,在其中使用了十进制数,但是稳定性差,已经销声匿迹了。)
计算机中的二进制数,有人则称之为:机器数。
其实,不必如此多愁善感!
即使表示形式不同,它们也是正常的数字。
由于计算机硬件的设计者,做出了极大的贡献,设计出来了各种运算电路。
所以,这些二进制数(即所谓的机器数),可以和正常的数字一样,可以加减乘除,而且还可以进行逻辑运算,如与或非 ... 。
因此,在进行软件编程时,完全可以把它们就当成普通的数字、正常的数字、阿拉伯数字。而不必纠结它们是什么电压什么电平什么机器数了。
二进制数与各种信息
二进制数在计算机中,可以代表各种不同的信息,如:数字、英文字符、汉字、声音、图像、控制信息、状态信息等等。
那么,随便看到一组二进制数,它究竟什么东西呢?
这就取决于你用什么算法来对待它们了。
如果你按照无符号数的规则对它进行计算,它就是无符号数;
如果你按照有符号数的规则对它进行计算,它就是有符号数;
如果你按照 BCD 码的规则对它进行处理,它就是 BCD 码形式的数字;
... ... 。
算法,是计算机的灵魂!
二进制数,只是任人揉搓的附属品而已。
有人说,计算机中的数,有两种:无符号数、有符号数。
这说法,是错误的。
数,只有一种。
而处理方法、思路、算法,以及由此编写出来的程序,有两种。
当然,各种处理程序,实际上,早已经是有无数种了。
一个字节的二进制数
在计算机中,是以 “字节” 为一个基本存储单位。
一个字节就是八位二进制数,其表示范围是:0000 0000 ~ 1111 1111。
(在某些教材上,偏要用五位、六位这样的二进制数来教学,真奇怪!)
八位二进制数,共有 2^8 = 256 个不同的组合。
它们可以写成等效的十六进制数:00H ~ FFH。这样,看起来就比较简单了。
也可以写成等效的十进制数:0 ~ 255。这种写法,就是 “无符号数”。
把它们标注在数轴上,如下图所示:
计算机中的二进制数和它代表的 “无符号数”,是直接相等的,不需要做任何变换。
也可以说,在计算机中,只有二进制的无符号数。
这些二进制数,能够代表各种信息,代表有符号数,当然也是可以的。
移码
以移码形式代表数字,是最简单的形式。
把一个字节的移码标注在数轴上,如下图所示:
两者的对应关系,非常直观。
就是把所有的数字都向右平移了 128,大概这就是 “移码” 名称的来源吧。
换算公式是: [ X ]移 = X + 128, -128 <= X < 128。
把 “有符号数 X” 加上 128,就成了计算机中的 “移码”。
把 “移码” 减去 128,就得到它所代表的 “有符号数 X”。
另外:
数字 0 ~ 9,加上 3,就构成了 “余三码”。
数字 0 ~ 9,加上 48,这就是 “ASCII 码” 了。
移码的应用场合还是很多的。
多数 AD 转换器产生的数字,就是用移码表示采样数据的。
比如电子秤,由传感器送来的数据,需要再加减一个差值,才是真实的重量数值。
在浮点数中,也用到了移码。
补码
为了方便计算,在计算机中,普遍使用 “补码” 代表 “有符号数”。
把它们标注在数轴上,如下图所示:
看起来,有点复杂!
零和正数不动,只是把负数向右平移 256 个数值。
这样做,数值的计算,就比较方便了。
为什么方便? 此事有专门的文章进行介绍,在此就不多说了。
有符号数 X 与补码的转换公式如下。
X >=0: [ X ]补 = X ;0 和正数不变。
X < 0: [ X ]补 = X + 256 ;256 是 8 位二进制数的计数周期。
有兴趣的读者可以去查看计算机类的书籍,从中也可以找到这个式子。
补码和移码的互换
从前面的示意图中可以看出,将移码加上 128,就变成了补码。
同样,将补码加上 128,也就变成了移码。
(如有进位,就忽略掉。)
对于任意位数的二进制数来说,只要把最高位取反,就可以实现移码和补码的互换。
数值大小的比较
一般的阿拉伯数字,人,一眼就能看出它们的谁大谁小。
计算机中的移码、补码,它们代表的数字的大小,可怎么比较呢?
补码和它代表的数字,对应关系有点乱。正数负数的位置,是颠倒的。
你可再去看看前面的示意图。
移码和其代表的数字,对应关系简单,就是整体平移过来的。
较大的数值,对应的移码,也是较大的。
所以,想要知道数值谁大谁小,就看它们的移码吧,一目了然!
求两者的差值,也可以用移码来相减,结果肯定是正确的。
你看懂了这些,就能明白:
为什么浮点数的阶码要用移码形式,而不用常说的补码。
本文完