二进制,顾名思义,就是逢二进一的数字系统。逢二进一,也就是说,只会出现0和1两种数字。这应该是最简单的数字系统了吧。你也许听别人提过,电脑那家伙笨的很,只知道0和1。哈哈,现在的绝大多数计算机的确是基于二进制运行的。说到这,你不是不很自豪呢?我比计算机可要知道的太多了,现在,就让我们走进2的世界吧。
《道德经》有云:道生一,一生二,二生三,三生万物。现在看来功能强大无比的计算机,竟是建立在一串串不起眼的0、1上,让人不得不相信纷繁复杂的世界背后,一定蕴藏着一条简洁到极致的真理。
这时候聪明的你肯定会犯嘀咕了,既然计算机只认识0和1,那负数怎么表示呢?是吧,没有“-”号,怎么表示负数呢?当然也是用0或1来表示了。
这里说两个新概念,比特(bit)和字节(byte)。计算机中,一位数字称为1个比特,8位数字称为1个字节。为什么要引入字节的概念呢?这是因为1个比特只能表示两种不同的事物,而1个字节有8个比特,可以表示2^8(256)种不同的事物。那为什么一个字节是8个比特而不是9个、10个呢?实际上,字节这个概念最早是IBM提出来的,而IBM使用字节的一个原因则是它们易于以BCD这种格式保存(参见《编码的奥秘》)。
既然采用一个字节进行运算,那我们完全可以约定,这8个比特的其中一位,用来标识正负。而其中的一种约定就是,最高位的比特用来标识正负号,0代表正数,1代表负数。
好了,现在能表示正负数了。既然数都可以表示了,那就该做运算了。
现在,我们实现一个8位加法机,实现7位的加减法。1个字节能表示的数的范围是-128~127。
一. 先来做加法运算吧:
一:
0000 0001
0000 0011
---------·
0000 0100
这个很简单,一瞅就能2看出来结果是“0000 0100”。二
0100 0000
0100 0000
---------·
1000 0000
咦,不对呀。两个正数相加,结果怎么是个负数?三
1010 0001
1100 0010
---------·
0110 0011
这下两个负数相加,结果怎么是正数了?
这就是溢出的问题了。两个正数相加得到负数,称为正溢出。两个负数相加得到正数,称为负溢出。
加法还简单,减法怎么做呢?
减法就是加上一个负数。前面说了,负数就是最高位为1的数。实际上,负数在计算机内部是采用2的补码形式存储的。2的补码是什么呢?它的转换步骤如下:
比如2的2进制是 0000 0010。现在看如何存储-2
- 逐位取反。
0000 0010 --> 1111 1101 - 加1
1111 1101
0000 0001
---------·
1111 1110
所以,-2在计算机中存储的是1111 1110,而不是1000 0010。
为什么采用2的补码呢?
先看我们最习惯的10进制看吧,24 - 16 = 8,这是两位数的减法,两位数中,最大的数是99,那么,用99减去被减数肯定就不需要借位了是吧,于是24 - 16 = 8 --> 24+(99-16) + 1 - 100 = 8。
- 接下来我们看下 4 - 2:
4是0000 0100,-2是1111 1110
0000 0100
1111 1110
---------·
0000 0010
这里生了什么呢?
0000 0100 + (1111 1111 - 0000 0010) + 1 - 1 0000 0000。是不是跟10进制里面的一样?取反就是拿8位数里最大的那个数-->1111 1111减去当前数。最后要减去1 0000 0000,因为我们只有8位,这里溢出的1就自动舍弃了。 - 那如果是2 - 4呢?
2是0000 0010,-4呢?0000 0100-->1111 1011-->1111 1100
0000 0010
1111 1100
---------·
1111 1110
1111 1110是多少呢?我们以前说过是-2。结果也是对的。 - -2-2呢?
1111 1110
1111 1110
---------·
1111 1100
结果也是对的。都是一个道理。
好了,现在我们有1个字节,可以表示256种不同的事物,我们可以给符号以及字母编码来表示文本,这就是ASCII码了。
最后,提一下16进制。为什么提16进制呢?因为2^4=16。4个比特的数字对应一个16进制的数字,一个字节就可以用两个16进制数字来表示,这样读起来比8个01数字串简单多了。下面是二进制、十进制、十六进制对照表:
二进制 | 十进制 | 十六进制 | 二进制 | 十进制 | 十六进制 |
---|---|---|---|---|---|
0000 | 0 | 0 | 1000 | 8 | 8 |
0001 | 1 | 1 | 1001 | 9 | 9 |
0010 | 2 | 2 | 1010 | 10 | A |
0011 | 3 | 3 | 1011 | 11 | B |
0100 | 4 | 4 | 1100 | 12 | C |
0101 | 5 | 5 | 1101 | 13 | D |
0110 | 6 | 6 | 1110 | 14 | E |
0111 | 7 | 7 | 1111 | 15 | F |