学计算机绕不开进制转换。这篇文章不背口诀,只讲人话:每个转换到底在干什么、为什么这么做、坑在哪里。看完记得动手算两遍,比看十遍都管用。

一、开头先说最重要的一句话

数没有变,只是写法变了。

十进制的 13,和二进制的 1101,和八进制的 15,和十六进制的 D,是同一个数。就像"十三"、"thirteen"、罗马数字"XIII"是同一个意思的不同写法。

所以进制转换不是"把一个数变成另一个数",而是换一套记号,把同一个数重新写一遍。想通这一点,后面所有方法你都不会觉得神秘。

二、认识一下这四种进制

进制

规则

用的数字

例子(都表示十进制的 13)

十进制(D)

逢十进一

0~9

13D

二进制(B)

逢二进一

0、1

1101B

八进制(O)

逢八进一

0~7

15O

十六进制(H)

逢十六进一

09、AF

0DH

末尾的字母是"身份牌":B = Binary,O = Octal,H = Hexadecimal,D = Decimal。没有后缀时默认十进制。

十六进制为什么冒出字母?因为它需要 16 个数字,09 只有 10 个不够用,只好借 AF 来代表 10、11、12、13、14、15。另外,十六进制数如果以字母开头(比如 D 开头),习惯在前面补个 0 写成 0DH,避免跟单词变量混淆。

为什么计算机偏偏偏爱二进制和十六进制?因为电路只认"高电平 / 低电平"两种状态,天然对应 0 和 1。而十六进制是二进制的缩写——后面你会看到,1 个十六进制数字正好顶 4 个二进制位。写代码时甩一长串 11010110 太累,用 D6 代替,又短又不容易抄错。

三、任何进制 → 十进制:按权展开(万能钥匙)

先学会这一招,它是所有转换里最基础的一个。

"权"就是每个位置的价值。十进制里 456 = 4×100 + 5×10 + 6×1,百位、十位、个位的权分别是 100、10、1——都是 10 的幂。

二进制同理,只是权换成了 2 的幂:

1101B = 1×8 + 1×4 + 0×2 + 1×1 = 13

从右往左,权依次是 1、2、4、8、16、32、64、128……(也就是 2 的 0、1、2、3 次方……)

八进制、十六进制一模一样,只是权换成 8 或 16 的幂:

15O  = 1×8 + 5×1 = 13
0DH  = 13×1 = 13          (D 代表 13)
93H  = 9×16 + 3×1 = 147
223O = 2×64 + 2×8 + 3×1 = 147

小数部分也一样,只是权变成比 1 小的数:二进制小数点后各位的权依次是 0.5、0.25、0.125……

0.101B = 1×0.5 + 0×0.25 + 1×0.125 = 0.625

先背下这张 2 的幂速查表,后面到处要用:

2⁰=1   2¹=2   2²=4   2³=8   2⁴=16   2⁵=32
2⁶=64  2⁷=128  2⁸=256  2⁹=512  2¹⁰=1024

四、十进制 → 二进制

整数:除 2 取余,余数倒着读

做法:不断除以 2,记下每一步的余数,直到商为 0,然后从最后一步的余数往前读

以 13 为例:

13 ÷ 2 = 6 …… 余 1   ↑
 6 ÷ 2 = 3 …… 余 0   ↑
 3 ÷ 2 = 1 …… 余 1   ↑
 1 ÷ 2 = 0 …… 余 1   ↑  从下往上读:1101

所以 13 = 1101B。

为什么倒着读? 因为第一次除出来的余数是"个位"(最低位),最后除出来的才是最高位。写数时高位在前面,所以要把顺序倒过来。

为什么这样做是对的? 每次除以 2,余数恰好暴露出最低一位:13 是奇数,最低位必是 1;除完剩 6 是偶数,下一位是 0……相当于把"13 = 8 + 4 + 1"这件事一层层剥出来。

小数:乘 2 取整,正着读

做法:小数部分不断乘 2,每次"溢出"到整数部分的那个数字,就是下一个二进制位,按产生的顺序往下读

以 0.625 为例:

0.625 × 2 = 1.25  → 取 1,剩 0.25
0.25  × 2 = 0.5   → 取 0,剩 0.5
0.5   × 2 = 1.0   → 取 1,剩 0,结束

按顺序读:0.101B。

一个重要的坑:很多小数是乘不尽的!比如 0.1:

0.1 × 2 = 0.2
0.2 × 2 = 0.4
0.4 × 2 = 0.8
0.8 × 2 = 1.6 → 剩 0.6
0.6 × 2 = 1.2 → 剩 0.2   ← 开始循环了
……

0.1 的二进制是 0.0001100110011…无限循环。这就是计算机里 0.1 + 0.2 ≠ 0.3 的根源——再大的内存也装不下无限位,只能截断,于是有了误差。

快捷法:凑 2 的幂(熟练后推荐)

把数拆成 2 的幂之和,哪位有就在哪位写 1。从高往低逐位判断,每步只做减法:

45 里有 32 → 剩 13     → 这位写 1
13 里有 16 吗?没有    → 写 0
13 里有 8  → 剩 5      → 写 1
5  里有 4  → 剩 1      → 写 1
1  里有 2 吗?没有     → 写 0
1  里有 1  → 剩 0      → 写 1

结果:45 = 101101B。比老老实实做长除法快得多。

验算习惯(强烈推荐)

转完把二进制按权展开加回去:1101 = 8 + 4 + 0 + 1 = 13 ✓。三秒钟的事,转错了马上能发现。

五、二进制 ↔ 八进制:3 位一组

为什么是 3 位? 因为 2³ = 8:三个二进制位恰好能表示 0~7,正好对应一个八进制数字。所以八进制本质上就是二进制的缩写。

二进制 → 八进制:以小数点为界,整数部分向左每 3 位一组,小数部分向右每 3 位一组,每组换成一个八进制数字。

不够 3 位怎么办?补 0。整数部分在前面补,小数部分在后面补。原则是:补零不能改变数值的大小,所以只能往远离小数点的方向补。

例 1:11010110B

11 010 110
→ 补成 011 010 110
→ 011=3   010=2   110=6
→ 326O

例 2(带小数):0.1011B

0.101 1
→ 补成 0.101 100
→ 101=5   100=4
→ 0.54O

八进制 → 二进制:反过来,一位拆三位。每个八进制数字写成 3 位二进制,必须写满 3 位(包括开头的 0):

52O = 101 010 = 101010B
3O  = 011     ← 别写成 11

六、二进制 ↔ 十六进制:4 位一组

和八进制一模一样的把戏,只是 2⁴ = 16,改成每 4 位一组

先背下这张对照表(这是全文唯一需要"死记"的部分,记熟后终身受用):

十六进制

二进制

十六进制

二进制

0

0000

8

1000

1

0001

9

1001

2

0010

A

1010

3

0011

B

1011

4

0100

C

1100

5

0101

D

1101

6

0110

E

1110

7

0111

F

1111

二进制 → 十六进制:4 位一组(补零规则同上:整数补头、小数补尾):

11010110B → 1101 0110 → D6H

十六进制 → 二进制:一位拆四位:

93H    = 1001 0011 = 10010011B
80H    = 1000 0000 = 10000000B

看到 80H,脑子里应该直接浮现 1000|0000 这两块——这就是"十六进制是二进制缩写"的含义,根本不用经过十进制中转。

七、八进制 ↔ 十六进制:二进制当桥

八进制和十六进制之间没有直达车,都要回二进制中转。道理很简单:机器内部只有二进制,八进制和十六进制都只是给人看的缩写,缩写之间互转自然要回到原文。

例:93H 转八进制。

第一步:每位十六进制数字展开成 4 位二进制:

93H = 1001 0011

第二步:把 4 位分组的"格子线"擦掉,回到完整二进制串,从右往左重新按 3 位分组:

10010011
→ 10 010 011
→ 补成 010 010 011
→ 2  2  3
→ 223O

验算:93H = 9×16 + 3 = 147;223O = 2×64 + 2×8 + 3 = 147 ✓

这里的坑:4 和 3 不是彼此的倍数,两套分组的格子线是错开的。必须先拆掉旧的分组、回到完整的二进制串,再重新分。不能把 1001、0011 两块各自直接转成八进制,那就错了。

八、十进制 ↔ 八进制 / 十六进制

两条路都通:

  • 路线 A(直达):除 8 取余 / 除 16 取余,规则和除 2 取余完全一样(余数倒着读)。做十六进制时,余数 1015 要写成 AF。

  • 路线 B(走桥):先转二进制,再 3 位 / 4 位分组。步骤多一点,但每一步都简单。

例:13 转十六进制。

  • 路线 A:13 ÷ 16 = 0 余 13 → D,所以 0DH。

  • 路线 B:13 = 1101B → 一组正好 4 位 → D → 0DH。

反方向(八进制 / 十六进制 → 十进制)就是第三节讲的按权展开,万能钥匙直接开。

九、最容易踩的坑汇总

  1. 余数倒着读:除基取余,第一个余数是最低位,要写在最右边。

  2. 补零方向:整数部分补在(左边),小数部分补在(右边)。原则:补零不能改变数值,只能往远离小数点的方向补。

  3. 一位拆多位时必须写满:八进制一位拆三位、十六进制一位拆四位,开头的 0 不能省,3O 是 011 不是 11。

  4. 八和十六互转必须回二进制重新分组:4 位组和 3 位组的格子线是错开的,不能拿旧分组直接换算。

  5. 小数可能乘不尽(如 0.1),按题目要求的精度截断即可。

  6. 验算:按权展开加回去对一遍,永远是最稳的自检。

十、一分钟速查表

想做的事

方法

任意进制 → 十进制

按权展开(各位的权是该进制的幂)

十进制整数 → 二进制

除 2 取余,倒着读

十进制小数 → 二进制

乘 2 取整,正着读

十进制 → 八 / 十六进制

除 8 / 除 16 取余;或先转二进制再分组

二进制 ↔ 八进制

3 位一组 / 一位拆三位

二进制 ↔ 十六进制

4 位一组 / 一位拆四位

八进制 ↔ 十六进制

都走二进制桥,擦掉旧格子线重新分组

写在最后

进制转换的全部秘密就两句话:

  1. 数没变,只是写法变了——所以任何转换都能用"按权展开"验算。

  2. 二进制是计算机的母语,八进制和十六进制都只是它的缩写——所以它们之间互转要回二进制中转。

把这两句话想通了,剩下的都是熟练度问题。找几个数自己转一遍、验算一遍,比背十遍口诀都管用。


下一篇预告:位串本身没有含义——同一个 1000 0000,按无符号读是 128,按补码读是 -128。补码是什么?为什么计算机要用它?见后续文章。