00 前言
熟悉编程的人都知道二进制总是一个让人晦涩难懂的词汇,只有大神级的程序员才有资格把玩它。 我们今天来重新认识一下二进制,了解编程中的数学知识和计算机为什么使用二进制?
01 先聊聊十进制
我们平时使用的是10进制计数法。
- 使用的数字有0、1、2、3、4、5、6、7、8、9共10个数字
- 数位有一定的意义,从右往左分别表示个位、十位、百位、千位……
上面的规则我们在小学数学都学过了,日常生活中也一直在用,是众所周知的常识。 在此权当复习,下面我们将通过实例来了解一下10进制计数法。
分解1024
首先,我们以 1024
这个数为例。1024表示的是由 1、0、2、4 这4个数字组成的一个称作 1024
的数(你这不废话)。
1024
这样并排的数字,因数位不同而意义相异。
- 1 表 示 “1000 的个数”
- 0 表 示 “100 的个数”
- 2 表 示 “10 的个数”
- 4 表 示 “1 的个数”
综上所述,1024 这个数是1个1000、0个100、2个10和4个1累加的结果。用数字和语言来冗长地说明有些无趣,下面就用图示来表现。
[ 1x1000 0x100 2x10 4x1 ]
如图,将数字的字体大小加以区别,各个数位上的数字 1、0、2、4 的意义便显而易见了。1000是 10x10x10
,即(10^3)
(10的3次方),100是 10x10
,即(10^2)
(10的2次方)。因此,也可以写成如下形式(请注意箭头所示部分)。
[ 2x10^3 5x10^2 0x10 3x1 ]
再则,10是 (10^1)
(10的1次方),1是 (10^0)
(10的0次方),所以还可以写成如下形式。
[ 2x10^3 5x10^2 0x10^1 3x10^0 ]
千位、百位、十位、个位,分别可称作 (10^3)
的位、(10^2)
的位、(10^1)
的位、(10^0)
的位。 10制计数法的数位全都是(10^n)
的形式。这个10称作10进制计数法的基数或底。
基数 10右上角的数字——指数,是 3、2、1、0 这样有规律地顺次排列的,这点请记住。
[ 2x10^3 5x10^2 0x10^1 3x10^0 ]
02 二进制计数法
计算机在处理数据时使用的是2进制计数法。从10进制计数法类推,便可很快掌握它的规则。
- 使用的数字只有0、1,共2种。
- 从右往左分别表示1位、2位、4位、8位
用2进制计数法来数数,首先是0,然后是1,接下去···不是2,而是在1上面进位变成10,继而是11,100,101……
下面的表格展示了0到79的数的10进制计数法和2进制计数法。
10进制 | 2进制 | 10进制 | 2进制 | 10进制 | 2进制 | 10进制 | 2进制 |
---|---|---|---|---|---|---|---|
0 | 0 | 20 | 10100 | 40 | 101000 | 60 | 111100 |
1 | 1 | 21 | 10101 | 41 | 101001 | 61 | 111101 |
2 | 10 | 22 | 10110 | 42 | 101010 | 62 | 111110 |
3 | 11 | 23 | 10111 | 43 | 101011 | 63 | 111111 |
4 | 100 | 24 | 11000 | 44 | 101100 | 64 | 1000000 |
5 | 101 | 25 | 11001 | 45 | 101101 | 65 | 1000001 |
6 | 110 | 26 | 11010 | 46 | 101110 | 66 | 1000010 |
7 | 111 | 27 | 11011 | 47 | 101111 | 67 | 1000011 |
8 | 1000 | 28 | 11100 | 48 | 110000 | 68 | 1000100 |
9 | 1001 | 29 | 11101 | 49 | 110001 | 69 | 1000101 |
10 | 1010 | 30 | 11110 | 50 | 110010 | 70 | 1000110 |
11 | 1010 | 31 | 11111 | 51 | 110011 | 71 | 1000111 |
12 | 1100 | 32 | 100000 | 52 | 110100 | 72 | 1001000 |
13 | 1101 | 33 | 100001 | 53 | 110101 | 73 | 1001001 |
14 | 1110 | 34 | 100010 | 54 | 110110 | 74 | 1001010 |
15 | 1111 | 35 | 100011 | 55 | 110111 | 75 | 1001011 |
16 | 10000 | 36 | 100100 | 56 | 110111 | 76 | 1001100 |
17 | 10001 | 37 | 100101 | 57 | 111001 | 77 | 1001101 |
18 | 10010 | 38 | 100110 | 58 | 111010 | 78 | 1001110 |
19 | 10011 | 39 | 100111 | 59 | 111011 | 79 | 1001111 |
分解1100
在此,我们以2进制表示的1100 (2 进制数的 1100) 为例来探其究竟。
1100
和10进制计数法一样,并排的数字,各个数位都有不同的意义。从左往右依次为:
- 1 表 示 “8 的个数”
- 1 表 示 “4 的个数”
- 0 表 示 “2 的个数”
- 0 表 示 “1 的个数”
也就是说,2进制的1100是1个8、1个4、0个2和0个1累加的结果。这里出现的8、4、2、1,分别表示 (2^3)
、(2^2)
、(2^1)
、(2^0)
即2进制计数法的1100,表示如下意思。
[ 1x2^3 1x2^2 0x2^1 0x2^0 ]
这样计算就能将2进制计数法的1100转换为10进制计数法。
[ 1 x 2^3 1 x 2^2 0 x 2^1 0 x 2^0 = 1 x 8 1 x 4 0 x 2 0 x 1 qquadqquadqquad;,= 8 4 0 0 qquad;,= 12 ]
由此可以得出,2进制的1100若用10进制计数法来表示,则为12。
基数转换
接下来我们试着将10进制的12转换为2进制。这需要将12反复地除以2(12除以2,商为6; 6再除以2,商为3; 3再除以2……),并观察余数为 “1” 还是 “0”。余数为0则表示“除完了”。随后再将每步所得的余数的列(1和0的列)逆向排列,由此就得到2进制表示了。
代码语言:javascript复制12 / 2 = 6 (余0)
6 / 2 = 3 (余0)
3 / 2 = 1 (余1)
1 / 2 = 0 (余1)
那么10进制的12转换为二进制就是 1100
。同样我们试将10进制的1024转换为2进制计数法。
1024 / 2 = 512 (余0)
512 / 2 = 256 (余0)
256 / 2 = 128 (余0)
128 / 2 = 64 (余0)
64 / 2 = 32 (余0)
32 / 2 = 16 (余0)
16 / 2 = 8 (余0)
8 / 2 = 4 (余0)
4 / 2 = 2 (余0)
2 / 2 = 1 (余0)
1 / 2 = 0 (余1)
可以知道1024用2进制表示为 10000000000
。各个数位的权重如下:
[ 1x2^11 0x2^10 0x2^9 0x2^8 1x2^7 1x2^6 0x2^5 0x2^4 0x2^3 1x2^2 1x2^1 1x2^0 ]
在 10进制中,基数为10,各个数位是以 (10^n)
的形式表现的。而2进制中,基数为2, 各个数位是以 (2^n)
的形式表现的。从10进制计数法转换为2进制计数法,称作10进制至2进制的基数转换。
03 计算机中为什么采用2进制计数法
计算机中一般釆用2进制计数法,我们来思考一下原因。计算机是由逻辑电路组成的,电路中通常只有两个状态,开关的接通和断开, 这两种状态正好可以用“1”和“0”表示。计算机在表示数的时候,会使用以下两种状态。
- 开关切断状态
- 开关连通状态
虽说是开关,但实际上并不需要机械部件。总之,它能够形成两种状态,这两种状态,分别对应0和1这两个数字。
- 开关切断状态 ··· 0
- 开关连通状态 ··· 1
1个开关可以用0或1来表示,如果有许多开关,就可以表示为许多个0或1。你可以想象这里排列着许多开关,各个开关分别表示2进制中的各个数位。这样一来,只要增加开关的个数,不管是多大的数字都能表示出来。
电脑的基层部件是由集成电路组成的,这些集成电路可以看成是一个个门电路组成,(当然事实上没有这么简单的)。当计算机工作的时候,电路通电工作,于是每个输出端就有了电压。电压的高低通过模数转换即转换成了二进制:高电平是由1表示,低电平由0表示。也就是说将模拟路转换成为数字电路。这里的高电平与低电平可以人为确定,一般地,2.5伏以下即为低电平,3.2伏以上为高电平。 电子计算机能以极高速度进行信息处理和加工,包括数据处理和加工,而且有极大的信息存储能力。数据在计算机中以器件的物理状态表示,采用二进制数字系统,计算机处理所有的字符或符号也要用二进制编码来表示。
当然,做成能够表示0〜9这10种状态的开关,进而让计算机釆用10进制计数法,这在理论上也是可能的。但是,与0和1的开关相比,必定有更为复杂的结构。
另外,请比较一下面表格所示的加法表。2进制的表比10进制的表简单得多吧。若要做成1位加法的电路,采用2进制要比10进制更为简便。
10进制加法表
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
2 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
3 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
5 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
6 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
7 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
8 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
9 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
2进制加法表
| 0 | 1 |
---|---|---|
0 | 0 | 1 |
1 | 1 | 10 |
不过,比起10进制,2进制的位数会增加许多,这是它的缺点。例如在10进制中2503只有4位,而在2进制中要表达同样的数则需要100111000111共12位数字。这点从表1-2中也显而易见。
人们觉得10进制比2进制更容易处理,是因为10进制计数法的位数少,计算起来不容易发生错误。此外,比起2进制,釆用10进制能够简单地通过直觉判断出数值的大小。人的两手加起来共有10个指头,这也是10进制更容易理解的原因之一。
不过,因为计算机的计算速度非常快,位数再多也没有关系。而且计算机不会像人类 那样发生计算错误,’ 不需要靠直觉把握数字的大小。对于计算机来说,处理的数字种类少、 计算规则简单就最好不过了。
让我们来总结一下。
- 在10进制计数法中,位数少,但是数字的种类多。
- → 对人类来说,这种比较易用。
- 在2进制计数法中,数字的种类少,但是位数多。
- → 对计算机来说,这种比较易用。
鉴于上述原因,计算机釆用了2进制计数法。 人类使用10进制计数法,而计算机使用2进制计数法,因此计算机在执行人类发出的任务时,会进行10进制和2进制间的转换。计算机先将10进制转换为2进制,用2进制进行计算,再将所得的2进制计算结果转换为10进制。
按位计数法
什么是按位计数法
我们学习了10进制和2进制两种计数法,这些方法一般称作按位计数法。除了10进制和2进制以外,还有许多种类的按位计数法。在编程中,也常常使用8进制和16进制计数法。
8进制计数法
8进制计数法的特征如下:
- 使用的数字有0、1、2、3、4、5、6、7共8种
- 从右往左分别为
(8^0)
的位、(8^1)
的位、(8^2)
的位、(8^3)
的位···(基数是8)
16进制计数法
16进制计数法的特征如下:
- 使用的数字有0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F共16种
- 从右往左分别为
(16^0)
的位、(16^1)
的位、(16^2)
的位、(16^3)
的位···(基数是16)
在16进制计数法中,使用A、B、C、D、E、F (有时也使用小写字母a、b、c、d、e、f) 来表示10以上的数字。
N进制计数法
一般来说,N进制计数法的特征如下:
- 使用的数字有0,1,2,3,···,N-1, 共 N 种
- 从右往左分别为
(N^0)
的位、(N^1)
的位、(N^2)
的位、(N^3)
的位··· (基数是N)
例如,N 进制计数法中,4位数 (a_3a_2a_1a_0)
为
[ a_3xN^3 a_2xN^2 a_1xN^1 a_0xN^0qquad(a_3、a_2、a_1、a_0是0〜N-1中的数字) ]
04 总结
二进制的优点
- 技术实现简单,计算机是由逻辑电路组成,逻辑电路通常只有两个状态,开关的接通与断开,这两种状态正好可以用“1”和“0”表示。
- 简化运算规则:两个二进制数和、积运算组合各有三种,运算规则简单,有利于简化计算机内部结构,提高运算速度。
- 适合逻辑运算:逻辑代数是逻辑运算的理论依据,二进制只有两个数码,正好与逻辑代数中的“真”和“假”相吻合。
- 易于进行转换,二进制与十进制数易于互相转换。
- 用二进制表示数据具有抗干扰能力强,可靠性高等优点。因为每位数据只有高低两个状态,当受到一定程度的干扰时,仍能可靠地分辨出它是高还是低。