进制 - 详解

世界上有10种人,懂二进制的和不懂二进制的。还有一种以为这只是个二进制笑话的。

一. 数字系统

1. 远古时期🔮:

在很久很久以前。。

  1. 结绳记事
    结绳记事
  2. 石板刻线

弊端:数字越大,越难记录😓

于是,各个地方的人类发明了更为先进的计数方法。。。

2. 非位置化数字系统:

非位置化数字系统中,符号所在位置与其大小无关,数字的大小就是各个符号所表示的大小直接相加或相减的结果。

罗马数字就是一个典型的例子:

VVV = 5 + 5 + 5 = 15 != 555

3. 位置化数字系统:

位置化数字系统中,符号所占据的位置决定了其表示的值,数字的大小需要视各个符号所表示的大小及其所在位置而定。

它包括:
二进制(Binary)/八进制(Octal)/十进制(Decimal)/十六进制(Hexadecimal)/…

555 = 500 + 50 + 5 = 555 != 15


由于非位置化数字系统效率太低,现在基本不再使用,位置化数字系统成为主流👍。

🙌因为人有十根手指头,所以很自然的选择了十进制进行数学运算。
🖥那么为什么计算机却选择使用二进制进行运算和存储呢?

二. 计算机使用二进制的原因

其实在历史上,世界上第一台通用计算机——ENIAC[1] 使用的就是十进制。
但这台计算机运行还得靠手动插线拔线,非常麻烦且不可靠:

ENIAC

后来,现代计算机之父——冯·诺依曼[2] 提出:采用二进制更有效率啊!

约翰·冯·诺依曼

这是因为计算机是由电子元件组成的,而电子元件可以非常明确的表示出两种状态:通电/断电
这两种状态非常适合用于二进制的表示:即1/0

除了硬件实现简单之外,使用二进制还有抗干扰能力强的特点:
即使电压发生轻微波动,计算机也能很容易地分辨出表示1的高电平和表示0的低电平,从而减少误差。

再其次,二进制的符号“1”“0”恰好与逻辑运算中的“对”(true)“错”(false)对应,便于计算机进行逻辑运算

等等。。

三. 进制转换⇄

在学习进制转换之前,我们先要理解好十进制的本质。

1. 十进制的本质:

十进制是基数为10的数字系统,逢十进一

使用10个可用符号(0~9)来表示一个数字,数字的位置从右往左依次是个位、十位、百位、千位…,对应的权重依次为:100、101、102、103

如图:

十进制例子

这个数字的大小就等于:

1 × 103 + 1 × 102 + 4 × 101 + 5 × 100 = 1145
(由于这里权重就是在以十进制描述,因此十进制数字的大小其实就是这个数字本身)

2. 二进制的本质&二进制转换十进制:

二进制是基数为2的数字系统,逢二进一

使用2个可用符号(0&1)来表示一个数字,数字的位置从右往左依次是个位、二位、四位、八位…,对应的权重依次为:20、21、22、23

如图:

二进制例子

这个二进制数字所代表的十进制数字就是:

1 × 23 + 0 × 22 + 1 × 21 + 1 × 20 = 11

(这里我们仍然以十进制描述权重,所以所得结果就是二进制数字对应的十进制数字)


问:二进制数101001对应的十进制数?

🎉恭喜你已经学会了二进制向十进制的转换。

八进制和十六进制又是什么鬼?

3. 类比:八进制/十六进制转十进制:

Ⅰ. 八进制转十进制:

八进制的本质同理,不再赘述。

🌰栗子:八进制数277对应的十进制数?

2 × 82 + 7 × 81 + 7 × 80 = 191

Ⅱ. 十六进制转十进制:

十六进制就有点不同了,对于10~15的数字,我们采用字母A~F来进行表示

十进制 十六进制
10 A
11 B
12 C
13 D
14 E
15 F

(对于基数大于十的进制的字符替换规则同理)

🌰栗子:十六进制数2AE对应的十进制数?

2 × 162 + 10 × 161 + 14 × 160 = 686

4. 十进制转二进制:

要把十进制数转化为对应的二进制数,需要不断地将十进制数字除以2(商),获取商和余数,直到商为0,再将所得余数倒序排列,所得数字即为该十进制数对应的二进制数。

如图:

十进制转二进制

💡以下是证明过程

设十进制数D对应的二进制为:
B = XNXN-1…X2X1(Xi = 0 或 1)

根据二进制定义:
D = X1 × 20 + X2 × 21 + … + XN × 2(N-1)

将 D 除以 2:
D ÷ 2 = (X1 × 20 + X2 × 21 + … + XN × 2(N-1)) ÷ 2 = X1 ÷ 2 + X2 × 20 + X3 × 21 + … + XN × 2(N-2)

因为X1只能是0或1,在式子中唯独不能被2整除,所以:

  • 余数 = X1(即二进制的最低位)
  • 新商 = X2 × 20 + X3 × 21 + … + XN × 2(N-2)

继续对新商重复此过程:

  • 第二次除以 2,余数 = X2
  • 第三次除以 2,余数 = X3
  • 第N次除以 2,余数 = XN,商为0,结束

将余数按计算顺序倒序排列:XNXN-1…X2X1,正好就是原始的二进制数B。

也可以从移位的视角来看:

除以2取余的操作,相当于把第一位二进制数作为余数提出来的同时,将所有第一位前的数统一向右移动了一位
因此不断除以2,就是从右往左依次剥离二进制数的每一位,除到商为0就是每一位都剥离完了。
😎


问:十进制数22对应的二进制数?

🎉恭喜你又学会了十进制向二进制的转换。

下课!(?)

其他进制呢?

5. 类比:十进制转八进制/十六进制:

Ⅰ. 十进制转八进制:

🌰栗子:十进制数900对应的八进制数?

如图:

十进制转八进制

Ⅱ. 十进制转十六进制:

🌰栗子:十进制数2717对应的十六进制数?

如图:

十进制转十六进制

6. 二进制/八进制/十六进制的互相转换:

知道了二/八/十六进制和十进制的互相转换,那么当要将二/八/十六进制进行互相转换时,是否还要大费周章地先将其转换为十进制,再将十进制转换为目标进制呢?😦

以下是一些简便的计算方法👇

  • 由于23 = 8,所以每3位二进制可以转换为一位八进制:

    🌰举个栗子:

    10111001(2) => 10|111|001 => 1 × 21 + 0 × 20|1 × 22 + 1 × 21 + 1 × 20|0 × 22 + 0 × 21 + 1 × 20 => 271(8)

  • 由于24 = 16,所以每4位二进制可以转换为一位十六进制:

    🌰举个栗子:

    10111001(2) => 1011|1001 => 1 × 23 + 0 × 22 + 1 × 21 + 1 × 20|1 × 23 + 0 × 22 + 0 × 21 + 1 × 20 => B9(16)

那么八进制又该如何转为十六进制呢?

采用二进制中转法比较简便:

步骤

  1. 先将八进制数每1位转为3位二进制(不足补零)。
  2. 将所得二进制数每4位一组转为十六进制(不足补零)。

🌰举个栗子:

271(8) => 010|111|001 => 10111001(2) => 1011|1001 => B9(16)


以上说的全部反过来,就是:

  • 八进制 → 二进制:每位八进制数展开为3位二进制。

  • 十六进制 → 二进制:每位十六进制数展开为4位二进制。

  • 十六进制 → 八进制:通过二进制中转:

    1. 十六进制 → 二进制(每1位转4位)。
    2. 二进制 → 八进制(每3位转1位)。

😎只要理解了本质,我们可以将这些进制的换算方法类推到其他所有进制!

恭喜你已经学会了整数的进制转换!

困难预警:下面板块为进阶知识,初学者可选择跳过

四. 进阶-小数的进制转换

1. 十进制和二进制的转换:

Ⅰ. 十进制和二进制小数的本质:

(1)十进制:

十进制小数

(2)二进制:

二进制小数

Ⅱ. 二进制转十进制:

既然:

101(2) = 1 × 22 + 0 × 21 + 1 × 20 = 5(10)

那么同理:

101.11(2) = 1 × 22 + 0 × 21 + 1 × 20 + 1 × 2-1 + 1 × 2-2 = 5.75(10)

🌰栗子:

0.101(2) = 0.625(10)

Ⅲ. 十进制转二进制:

要把十进制小数转化为对应的二进制小数,需要不断地将十进制数字乘以2(小数部分),获取结果的整数部分和小数部分,直到小数部分为0,再将所得整数部分顺序排列于小数点后,所得数字即为该十进制小数对应的二进制小数。(这里我们认为十进制数整数部分为0)

如图:

十进制转二进制

💡以下是证明过程

设十进制小数D对应的二进制为:
B = 0.X1X2X3…XN(Xi = 0 或 1)

根据二进制定义:
D = X1 × 2-1 + X2 × 2-2 + … + XN × 2-N

将 D 乘以 2:
D × 2 = (X1 × 2-1 + X2 × 2-2 + … + XN × 2-N) × 2 = X1 × 20 + X2 × 2-1 + X3 × 2-2 + … + XN × 2-(N-1)

因为X1是0或1,(X1 × 20)在式子中是唯一的整数,所以:

  • 整数部分 = X1(即二进制小数的小数点后第一位)
  • 小数部分 = X2 × 2-1 + X3 × 2-2 + … + XN × 2-(N-1)

继续对小数部分重复此过程:

  • 第二次乘以 2,整数部分 = X2
  • 第三次乘以 2,整数部分 = X3
  • 第N次乘以 2,整数部分 = XN,小数部分为0,结束

将整数部分按计算顺序排列:0.X1X2X3…XN,正好就是原始的二进制小数B。

也可以从移位的视角来看:

乘以2取整的操作,相当于把小数点后第一位二进制数作为整数部分提出来的同时,将所有小数点后第一位后的数统一向左移动了一位
因此不断乘以2,就是从左往右依次剥离二进制小数的每一位,乘到小数部分为0就是每一位都剥离完了。
😎


2. 重要提示❗:

Ⅰ. 无限循环小数:

只有能够拆分成若干个“分母是2的幂次的分数”的十进制小数才能被二进制用有限的数位表示

如:

0.125(10) = 1/23 => 0.001(2)

0.625(10) = 1/21 + 1/23 => 0.101(2)

而其他的十进制小数会转换为无限循环的二进制小数:

0.325(10) => 0.010 1001 1001 1001…(无限循环)

Ⅱ. 精度问题:🤯

  • 有限位数无法精确表示无限循环小数
    在计算机中,浮点数(如 floatdouble)的存储位数是有限的(如32位或64位),因此无限循环的二进制小数必须被截断,导致精度损失。

  • 示例

    • 如果计算机只能用 8位 存储小数部分:

      0.325(10) ≈ 0.01010011(2)

    • 转换回十进制:

      0.01010011(2) = 0.32421875(10)(误差:0.00078125)

    • 如果存储更多位(如64位双精度浮点数),误差会减小,但仍然无法完全精确

Ⅲ. 亿堆栗子:

  1. 🌰0.015(10) = 0.000 00011110101110000101 00011110101110000101…(无限循环)

  2. 🌰0.1011(2) = 0.6875(10)

  3. 🌰0.011(2) = 0.375(10)

3. 类比:其他进制:

Ⅰ. 其他进制转十进制:

  1. 每位数字乘以基数的负幂次。
  2. 将所有乘积相加,得到十进制值。

Ⅱ. 十进制转其他进制:

  1. 将小数部分乘以基数,记录整数部分。
  2. 再取小数部分,继续乘以基数,如此循环,直到小数部分为0或达到所需精度。
  3. 按计算顺序排列整数部分于小数点后,得到目标进制的小数。

Ⅲ. 二进制/八进制/十六进制的互相转换:

当要将二/八/十六进制小数进行互相转换时,同样有一些简便的计算方法。

  • 由于2-3 = 1/8,所以每3位二进制小数可以转换为一位八进制小数:(不足补零)

    🌰举个栗子:

    0.10111001(2) => 0.101|110|010 => 1 × 22 + 0 × 21 + 1 × 20|1 × 22 + 1 × 21 + 0 × 20|0 × 22 + 1 × 21 + 0 × 20 => 0.562(8)

  • 由于2-4 = 1/16,所以每4位二进制小数可以转换为一位十六进制小数:(不足补零)

    🌰举个栗子:

    0.10111001(2) => 0.1011|1001 => 1 × 23 + 0 × 22 + 1 × 21 + 1 × 20|1 × 23 + 0 × 22 + 0 × 21 + 1 × 20 => 0.B9(16)

那么八进制小数又该如何转为十六进制小数呢?

采用二进制中转法比较简便:

步骤

  1. 先将八进制小数每1位转为3位二进制小数(不足补零)。
  2. 将所得二进制小数每4位一组转为十六进制小数(不足补零)。

不太直观,证明一下:(八转二、十六转二为逆过程,不再赘述)

(1)二进制和八进制转换的证明:

0.b1b2b3b4b5b62=b12+b24+b38+b416+b532+b664+=(b1×4+b2×2+b3×18)+(b4×4+b5×2+b6×182)+=O18+O282+O383+=0.O1O2O38\begin{align*} 0.b_1 b_2 b_3 b_4 b_5 b_6 \ldots_2 &= \frac{b_1}{2} + \frac{b_2}{4} + \frac{b_3}{8} + \frac{b_4}{16} + \frac{b_5}{32} + \frac{b_6}{64} + \ldots \\ &= \left( \frac{b_1 \times 4 + b_2 \times 2 + b_3 \times 1}{8} \right) + \left( \frac{b_4 \times 4 + b_5 \times 2 + b_6 \times 1}{8^2} \right) + \ldots \\ &= \frac{O_1}{8} + \frac{O_2}{8^2} + \frac{O_3}{8^3} + \ldots \\ &= 0.O_1 O_2 O_3 \ldots_8 \end{align*}

(2)二进制和十六进制转换的证明:

0.b1b2b3b4b5b6b7b82=b12+b24+b38+b416+b532+b664+b7128+b8256+=(b1×8+b2×4+b3×2+b4×116)+(b5×8+b6×4+b7×2+b8×1162)+=H116+H2162+H3163+=0.H1H2H316\begin{align*} 0.b_1 b_2 b_3 b_4 b_5 b_6 b_7 b_8 \ldots_2 &= \frac{b_1}{2} + \frac{b_2}{4} + \frac{b_3}{8} + \frac{b_4}{16} + \frac{b_5}{32} + \frac{b_6}{64} + \frac{b_7}{128} + \frac{b_8}{256} + \ldots \\ &= \left( \frac{b_1 \times 8 + b_2 \times 4 + b_3 \times 2 + b_4 \times 1}{16} \right) \\ &\quad + \left( \frac{b_5 \times 8 + b_6 \times 4 + b_7 \times 2 + b_8 \times 1}{16^2} \right) + \ldots \\ &= \frac{H_1}{16} + \frac{H_2}{16^2} + \frac{H_3}{16^3} + \ldots \\ &= 0.H_1 H_2 H_3 \ldots_{16} \end{align*}

Ⅳ. 亿堆栗子:

  1. 🌰0.3125(10) => 八进制:

    0.3125 × 8 = 2.5 => 取2

    0.5 × 8 = 4.0 => 取4

    结果:0.3125(10) = 0.24(8)

  2. 🌰0.796875(10) => 十六进制:

    0.796875 × 16 = 12.75 => 取12(C)

    0.75 × 16 = 12.0 => 取12(C)

    结果:0.796875(10) = 0.CC(8)

  3. 🌰将 0.12(3) => 五进制:

    1. 转十进制:

      0.12(3)=1 × 3−1 + 2 × 3−2 ≈ 0.555…(10)

    2. 转五进制:

      0.555… × 5 = 2.777… => 取2

      0.777… × 5 = 3.888… => 取3

      0.888… × 5 = 4.444… => 取4

    结果:0.12(3) ≈ 0.234(5)(近似)


🎊完结撒花yeahh🎊

五. 其他の东东~

1. 存储单位:

在了解了进制后,我们还需要知道几个常用的计量单位:

  1. 比特(bit)

    表示一位二进制数字,即0或1

    是数据的最小存储单位

    例如二进制数字1011就是由4个比特组成的,分别是1、0、1、1

  2. 字节(byte)

    一个字节由8个比特组成

    1byte = 8bit

    它是计算机的基本存储单位

    1字节可以表示的最大二进制数字,是:11111111

    11111111(2) = 255(10)

还有其他常见单位及换算:

1KB(千字节 KiloByte) = 210B = 1024B

1MB(兆字节 MegaByte) = 210KB = 1024KB

1GB(吉字节 GigaByte) = 210MB = 1024MB

1TB(太字节 TeraByte) = 210GB = 1024GB

2. 不同进制数的读法:

如果你理解了数位,那么你就一定就能理解只有十进制才遵循“几千、几十、几百”的汉语读法
其他进制只能逐位地读出各位上的数字(或字母)

例如:

1(2) + 1(2) = 10(2)

不能读成:

一加一等于十(?)


在线进制转换工具:

在线进制转换

参考资料:

4分钟带你学会二进制

【最强干货】详解二进制,八进制,十进制,十六进制的相互转换

二进制,十进制转换进阶- 小数的二进制转换


  1. ENIACElectronic Numerical Integrator And Computer ”电子数字积分计算机”)。ENIAC是继ABC(Atanasoff-Berry Computer ”阿塔纳索夫-贝瑞计算机“)之后的第二台电子计算机,和第一台通用计算机,于1946年2月14日在美国宣告诞生。ENIAC的计算速度为每秒5000次加法或400次乘法,它是完全的电子计算机,能够重新编程,解决各种计算问题。 ↩︎

  2. 约翰·冯·诺依曼John von Neumann)对世界上第一台电子计算机ENIAC(电子数字积分计算机)的设计提出过建议,1945年3月他在共同讨论的基础上起草了一个全新的“存储程序通用电子计算机方案”——EDVACElectronic Discrete Variable Automatic Computer)。这对后来计算机的设计有决定性的影响,特别是确定计算机的结构,采用存储程序以及二进制编码等,一直为电子计算机设计者所遵循。 ↩︎