前言
说起进制,你有了解过嘛?你知道吗进制不仅是计算机基础中需要学习的一个重要部分,也是日常生活中随处可见的,比如生活中最常用的进制就是十进制,计算机底层使用的是二进制。本文就来带你了解一下什么是进制以及不同进制之间该如何转换。
介绍 |
从原始时代开始,其实就有了 “ 进制 ” 的存在,那时候原始人类为了维持日常生活,必须每天定时外出狩猎和采集果实保证自己的部落和妻儿有足够的食物,但世事无常,大肠包小肠。有时他们可能驮着大量的猎物或者食物满载而归,但有时又披着一身的伤痕回到部落一无所获。因此带回的食物有时是富余的,但有时却无法果腹。在一次次的经验教训中,这种数与量上的变化,慢慢产生了质变,使他们逐渐产生了 “ 数 ” 的概念,他们渐渐开始了解猎物的有与无、食物的多与少的差别,进而知道了一和多的区别,然后从无到有逐渐形成了数量的概念。
在后续的生活中,他们想到了用小石子检查放牧归来的羊的只数;用结绳的方法统计猎物的个数;用在木头上刻道的方法记录捕鱼的数量这些计数的方法。这些原始的计数方法表明,其实人类很早就产生了数学的概念,并开始逐渐向高级文明慢慢靠拢。
综上所述,人们用来计数的方式或方法就称为进制,也称为数制。例如上图中原始人类使用的结绳计数法就是一种计数的方法。不过在概念上,我们通常会将进制分为两种类型,进位计进制和非进位计进制。此外,现在用的最多就是进位计进制,所以一说到进制,如果没有特别指出,一般说的就是进位计进制。
在计算机中通常包含以下四种常见的进制 |
Binary:二进制,例如 0101B
,只有 0 和 1 两个数
Decimal:十进制,例如 102D
(D通常可省略不写),数字0-9,共十位
Octal:八进制,例如 45O
,数字从 0-7,共八位数字
Hexdecimal:十六进制,例如 34H
,共有 1-9、A-F 这些数,其中 A-F 表示 10-15 这几个数
在进位计进制中有两个非常重要的概念,基数 (Radix) 和位权 (Weight) 。
基数(Radix):R 进制中只允许出现 0, 1, 2, . . . , R-1 共 R 个数码,而 R 就称为 R 进制的基数。满 R 进 1,借 1 作 R。
位权(Weight):R 进制中,不同位置的 1 所表示的值不同,位号为 i 的 1 表示 Ri。位号 i 的确定以小数点为基准,向左分别为 0, 1, 2, 3, . . . , 向右分别为 -1, -2, -3, . . . 。
计算方法:按权展开法 |
R 进制转十进制使用按权展开法,其具体操作方式为:将R进制数的每一位数值用 Rk 形式表示,即幂的底数是 R,指数为 k,k 与该位小数点之间的距离有关。当该位位于小数点左边,k 值是该位和小数点之间数码的个数,而当该位位于小数点右边,k 值是负值,其绝对值是该位和小数点之间数码的个数 +1,即:
(anan−1an−2...a1a0a−1a−2...a−m)R=an×Rn+an−1×Rn−1+an−2×Rn−2+...+a1×R1+a2×R2+...+am×Rm(a_na_{n-1}a_{n-2}\;. . .\;a_1a_0a_{-1}a_{-2}\;. . .\;a_{-m})\;R = a_n × R^n + a_{n-1}~ × R^{n-1} + a_{n-2} × R^{n-2} +\;. . .\;+ a_1 × R^1 + a_2 × R^2 +\;...\;+ a_m \times R^m(anan−1an−2...a1a0a−1a−2...a−m)R=an×Rn+an−1 ×Rn−1+an−2×Rn−2+...+a1×R1+a2×R2+...+am×Rm
其中 0≤ai≤R−10 \leq a_i \leq R-10≤ai≤R−1,有一点要注意的是,RRR 进制中按权展开式的唯一性。
转换示例 |
运算规则:将 R 进制数 以 基数 和 位权数 方式 展开。
(1)、二进制转十进制
例1:(10100.01)2 转十进制数
(10100.01)2=1×24+0×23+1×22+0×21+0×20+0×2−1+1×2−2按权展开=1×24+1×22+1×2−2=16+4+14=20+0.25=(20.25)10\begin{align} (10100.01)_{2} & = 1 \times 2^{4} + \cancel{0 \times 2^{3}} + 1 \times 2^{2} + \cancel{0 \times 2^{1}} + \cancel{0 \times 2^{0}} + \cancel{0 \times 2^{-1}} + 1 \times 2^{-2} &\text{按权展开} \;\; \tag{1}\\ & = 1 \times 2^{4} + 1 \times 2^{2} + 1 \times 2^{-2} \tag{2}\\ & = 16 + 4 + \frac{1}{4} \tag{3} \\ & = 20 + 0.25 \tag{4} \\ & = (20.25)_{10} \tag{5} \end{align} (10100.01)2=1×24+0×23+1×22+0×21+0×20+0×2−1+1×2−2=1×24+1×22+1×2−2=16+4+41=20+0.25=(20.25)10按权展开(1)(2)(3)(4)(5)
其他示例:(1001.1)2 转十进制数、(10110110.11)2 转十进制数
(2)、七进制转十进制
例1:(604.01)7 转十进制数
(604.01)7=6×72+0×71+4×70+0×7−1+1×7−2按权展开=6×72+4×70+1×7−2=294+4+149=298+0.0204081632653=298.0204081632653≈(298.02)10\begin{align} (604.01)_{7} & = 6 \times 7^{2} + \cancel{0 \times 7^{1}} + 4 \times 7^{0} + \cancel{0 \times 7^{-1}} + 1 \times 7^{-2} &\text{按权展开} \tag{1}\\ & = 6 \times 7^{2} + 4 \times 7^{0} + 1 \times 7^{-2} \tag{2}\\ & = 294 + 4 + \frac{1}{49} \tag{3}\\ & = 298 + 0.0204081632653 \tag{4}\\ & = 298.0204081632653 \approx (298.02)_{10} \tag{5} \end{align} (604.01)7=6×72+0×71+4×70+0×7−1+1×7−2=6×72+4×70+1×7−2=294+4+491=298+0.0204081632653=298.0204081632653≈(298.02)10按权展开(1)(2)(3)(4)(5)
Tips
若在一个非零无符号二进制数后添加一个 0,形成的新数是原数的 2 倍。4 进制 4 倍;若在一个非零无符号二进制数后减去一个 0,形成的新数是原数的 12\frac{1}{2}21 倍。
计算方法:短除法 |
特例:将 (332)10(\frac{3}{32})_{10}\\[2ex](323)10 转换为二进制的数
方法一:(332)10=132+116=(0.00011)2(\frac{3}{32})_{10} = \frac{1}{32}+\frac{1}{16} = (0.00011)_{2}\\[2ex](323)10=321+161=(0.00011)2
方法二:(332)10=3×2−5=(11)2×(0.00001)2=(0.00011)2(\frac{3}{32})_{10} = 3 \times 2^{-5} = (11)_{2} \times (0.00001)_{2} = (0.00011)_{2} \\[2ex](323)10=3×2−5=(11)2×(0.00001)2=(0.00011)2
转换示例 |
(1)、十进制数转二进制
运算规则:将 十进制的整数作为 被除数,以二进制的基数 2 为 除数, 求余数 (反序书写),如果有小数部分则乘以 2 取整,直到小数部分等于 0 为止 (正序书写)。
例1:(121)10 转二进制数
(121)10=(1111001)2(121)_{10} = (1111001)_{2}(121)10=(1111001)2
例2:(75)10 转二进制数
(75)10=(1001011)2(75)_{10} = (1001011)_{2}(75)10=(1001011)2
例3:(255.86)10(255.86)_{10}(255.86)10 转二进制数
(255.86)10=(11111111.1101110000101000111101011100001010001111011)2(255.86)_{10} = (11111111.1101110000101000111101011100001010001111011)_{2}(255.86)10=(11111111.1101110000101000111101011100001010001111011)2
从上面的示例中可以得出一个结论,一个十进制数不一定能精确转化为二进制。
(2)、十进制转八进制
例1:(284)10(284)_{10}(284)10 转八进制
(284)10=(434)8(284)_{10} = (434)_{8}(284)10=(434)8
(3)、十进制转16进制
例1:(56)10(56)_{10}(56)10 转十六进制
(56)10=(38)16(56)_{10} = (38)_{16}(56)10=(38)16
例2:(351)10(351)_{10}(351)10 转十六进制
(351)10=(15F)16(351)_{10} = (15F)_{16}(351)10=(15F)16
计算方法 |
以二进制转换为八进制为例,反之正好相反
二进制与八进制编码对应表
二进制 | 八进制 |
---|---|
000 | 0 |
001 | 1 |
010 | 2 |
011 | 3 |
100 | 4 |
101 | 5 |
110 | 6 |
111 | 7 |
转换示例 |
(1)、二进制转八进制
运算规则:二进制的整数部分,从右向左依次取3位,不足三位补左补 0;二进制的小数部分,从左向右依次取3位,不足 3 位右补 0。
例1:(10101111.010)2(10101111.010)_{2}(10101111.010)2 转八进制数
(10101111.010)2=(257.2)8(10\;101\;111.\;010)_{2} = (257.2)_{8}(10101111.010)2=(257.2)8
(2)、八进制转二进制
运算规则:将每位八进制,看作十进制数,再将十进制转二进制,保留三位二进制长度。
例1:(16.3)8(16.3)_{8}(16.3)8 转二进制数
(16.3)8=(1110.011)2(16.3)_{8} = (1\;110.\;011)_{2}(16.3)8=(1110.011)2
计算方法 |
以二进制转换为十六进制为例,反之正好相反
二进制与十六进制编码对应表
二进制 | 十六进制 |
---|---|
0000 | 0 |
0001 | 1 |
0010 | 2 |
0011 | 3 |
0100 | 4 |
0101 | 5 |
0110 | 6 |
0111 | 7 |
1000 | 8 |
1001 | 9 |
1010 | A |
1011 | B |
1100 | C |
1101 | D |
1110 | E |
1111 | F |
转换示例 |
(1)、二进制转十六进制
运算规则:二进制的整数部分,从右向左依次取4位,不足4位左补零;二进制的小数部分,从左向右依次取4位,不足4位右补零
例1:(10101111.0100)2(10101111.0100)_{2}(10101111.0100)2 转十六进制
(10101111.0100)2=(AF.4)16(1010\;1111.\;0100)_{2} = (AF.4)_{16}(10101111.0100)2=(AF.4)16
每 4 位二进制数刚好对应一个 16 进制的数字,因为 24 = 16。
(2)、十六进制转二进制
4 个二进制位数,对应 1 个十六进制位数
运算规则: 将每个十六进制,看作十进制数,再将十进制数转二进制,保留 4 位二进制数长度。
例1:(3AC.D)16(3AC.D)_{16}(3AC.D)16 转二进制
(3AC.D)16=(1110101100.1101)2(3AC.D)_{16} = (11\;1010\;1100.\;1101)_{2}(3AC.D)16=(1110101100.1101)2
Tips
八进制、十六进制与二进制的转换运算,全部以二进制作为 “ 中介 ”。
计算机的底层通常会将表达式中的乘法 (或除法) 转化为加法和移位进行运算,例如:a×10=a×(8+2)=a×8+a×2=(a<<3)+(a<<1)a \times 10 = a \times (8 + 2) = a \times 8 + a \times 2 = (a<<3) + (a<<1)a×10=a×(8+2)=a×8+a×2=(a<<3)+(a<<1)
因为纯乘法计算非常耗时,且加法和移位运算都非常快,通过这种转换可以有效地提高运算的速度。
二进制数左移 K 位,相当于这个数乘以 2k2^{k}2k;二进制数右移 K 位,相当于这个数除以 2k2^{k}2k。