二进制、八进制与十六进制 —— 计算机的母语
一句话类比
二进制就像一盏灯的“开/关”两种状态,十六进制则是把 4 盏灯的状态用一个字母或数字来速记,八进制是把 3 盏灯的状态用一个数字来速记。
为什么计算机要用二进制?
现实世界
- 灯泡:只有 亮 或 灭。
- 开关:只有 开 或 关。
- 电线:只有 有电 或 无电。
计算机内部由几十亿个微小的“开关”(晶体管)组成。每个开关只有两种状态:导通 (1) 或 截止 (0)。
因此计算机天然只认识 0 和 1。
二进制的好处
- 抗干扰:即使电压有波动,0.8V 和 1.2V 都能正确识别为 1 或 0。
- 简单可靠:逻辑电路设计极其简单(与、或、非门)。
- 数学完备:任何整数、小数、文字、图片、声音都可以用 0 和 1 的组合表示。
二进制计数(用手指演示)
十进制 vs 二进制
| 十进制 | 二进制 | 解释 |
|---|---|---|
| 0 | 0 | 没有东西 |
| 1 | 1 | 一个单位 |
| 2 | 10 | 一位满了,进一位(类似十进制的 9→10) |
| 3 | 11 | 两位都是 1 |
| 4 | 100 | 又进一位 |
| 5 | 101 | |
| 6 | 110 | |
| 7 | 111 | |
| 8 | 1000 |
手势记忆法(用右手五根手指)
把右手五根手指从拇指到小指分别赋予权重:16, 8, 4, 2, 1(拇指=16,食指=8,中指=4,无名指=2,小指=1)。
- 弯曲手指 = 0,伸直 = 1。
- 你能表示 0~31 的所有数字。
例如:只伸直食指(8)和中指(4) → 8+4 = 12(二进制 01100 或更常用 1100)。
十六进制 —— 二进制的速记法(每4位一组)
为什么需要十六进制?
二进制写起来太长了:
1010 1110 0011 0101 这样的 16 位,人眼看着很累。
但是每 4 位二进制可以对应一个 十六进制数字(09, AF)。
对照表
| 二进制 (4位) | 十六进制 | 十进制 |
|---|---|---|
| 0000 | 0 | 0 |
| 0001 | 1 | 1 |
| 0010 | 2 | 2 |
| 0011 | 3 | 3 |
| 0100 | 4 | 4 |
| 0101 | 5 | 5 |
| 0110 | 6 | 6 |
| 0111 | 7 | 7 |
| 1000 | 8 | 8 |
| 1001 | 9 | 9 |
| 1010 | A | 10 |
| 1011 | B | 11 |
| 1100 | C | 12 |
| 1101 | D | 13 |
| 1110 | E | 14 |
| 1111 | F | 15 |
转换例子
- 二进制 1010 1110 → 分组:1010 = A,1110 = E → AE(十六进制通常写作 0xAE 或 AEh)
- 十六进制 3F → 3 = 0011,F = 1111 → 二进制 0011 1111
八进制 —— 二进制的另一种速记法(每3位一组)
为什么需要八进制?
在早期计算机(如 PDP-8、UNIX 权限)中,经常使用每 3 位一组,因为 3 位二进制刚好对应 0~7 八个数字,且不用引入字母,纯粹是数字。虽然现代编程中十六进制更常见,但八进制仍然出现在文件权限(chmod 755)、某些嵌入式代码字面量(以 0 开头的数字)以及位域分组中。
对照表
| 二进制 (3位) | 八进制 | 十进制 |
|---|---|---|
| 000 | 0 | 0 |
| 001 | 1 | 1 |
| 010 | 2 | 2 |
| 011 | 3 | 3 |
| 100 | 4 | 4 |
| 101 | 5 | 5 |
| 110 | 6 | 6 |
| 111 | 7 | 7 |
转换例子
- 二进制 10 1110 01(完整为 010 111 001)→ 分组(从右向左每3位):010 = 2,111 = 7,001 = 1 → 八进制 0271(通常写作 0271 或 0o271)
- 八进制 755 → 7=111,5=101,5=101 → 二进制 111 101 101
注意陷阱
在 C/C++ 中,以 0 开头的整数字面量表示八进制,例如 0755 实际等于十进制 493,很容易引起歧义。C++11 开始推荐使用 0o755 表示八进制。
模拟练习:手算转换
题目1:将十进制数 58 转换为二进制,再转换为十六进制。
-
十进制 → 二进制(短除法)
- 58 ÷ 2 = 29 余 0
- 29 ÷ 2 = 14 余 1
- 14 ÷ 2 = 7 余 0
- 7 ÷ 2 = 3 余 1
- 3 ÷ 2 = 1 余 1
- 1 ÷ 2 = 0 余 1
- 从下往上读余数:111010(二进制)
-
二进制 → 十六进制
- 从右向左每 4 位一组:0011 1010(左边补零到4位)
- 0011 = 3,1010 = A → 0x3A
答案:十进制 58 = 二进制 111010 = 十六进制 0x3A
题目2:将二进制 1011001110 转换为八进制。
- 从右向左每3位分组:1 011 001 110 → 补成 001 011 001 110
- 001=1,011=3,001=1,110=6 → 八进制 01316(或 0o1316)
自己再试一个:十进制 85 → 二进制?→ 十六进制?→ 八进制?
(答案在文末)
真实世界例子
- 内存地址:0x7FFD43A2 比 01111111111111010100001110100010 好记。
- 颜色值:#FFA500(橙色) → R=255, G=165, B=0。
- 寄存器标志:x86 的 EFLAGS 寄存器长 32 位,用十六进制 0x00000246 描述。
- 文件权限:chmod 755 中的 755 就是八进制,表示 rwxr-xr-x。
自测题
-
1. 二进制 1101 等于十进制多少?
-
2. 十六进制 B3 等于二进制多少?
-
3. 八进制 37 等于十进制多少?又等于二进制多少?
-
4. 为什么计算机绝对不用十进制而用二进制?
自测题答案:
- 13(8+4+1)
- 1011 0011(B=1011,3=0011)
- 八进制 37 = 3*8 + 7 = 31 = 二进制 011111
- 因为计算机硬件只能可靠区分两种电压状态(高/低),二进制无论从电路实现还是抗干扰上都最可靠。
前置练习答案:85 = 二进制 1010101 = 十六进制 0x55(0101 0101)= 八进制 0125(001 010 101)。