⌨️ 第三章 数值和数据的处理方法
📄 一句话概括

人类十根手指所以用十进制,计算机电路只有通电和断电两种状态所以用二进制,十六进制则是给二进制【压缩打包】的方便写法——一个十六进制位正好对应四个二进制位。

📝 本节和前面几节的关系

第二章讲了【代码怎么变成指令】,而指令在机器眼里全是一串 0 和 1——本章就从【数字怎么表示】开始讲数据处理。回收 C++ 课 2.2 与树莓派课 7-1 的进制底子,这一篇把它们串成体系。

一、为什么会有不同的进制

进制就是【逢几进一】的计数规则:十进制逢十进一、二进制逢二进一、十六进制逢十六进一。基数(几)决定了每一位上有几种数字可用。

二、按权展开:任何进制读成十进制

每一位都有一个权(基数的幂,从右往左依次升):

二进制 101101 = 1x32 + 0x16 + 1x8 + 1x4 + 0x2 + 1x1 = 45
十六进制 2D   = 2x16 + 13x1 = 45

反过来【十进制转二进制】用除二取余、倒序读:45 除 2 得 22 余 1,再除得 11 余 0……把余数从下往上读就是 101101。

三、十六进制为什么存在

二进制写起来太长(一个字节 8 位),十进制又跟二进制对不上号。十六进制恰好卡在中间:2 的 4 次方是 16,所以:

1 个十六进制位 = 4 个二进制位
1 个字节(8 位二进制) = 2 个十六进制位
二进制 1011 1101  =  十六进制 BD

这就是为什么内存地址、颜色码(如 #FF6600)、MAC 地址全是十六进制——不是玄学,是打包。

四、编程语言里的写法

Python/C/Java 都用前缀区分进制(Python 演示):

print(bin(45))   # 0b101101  -> 二进制
print(oct(45))   # 0o55      -> 八进制
print(hex(45))   # 0x2d      -> 十六进制
print(int("101101", 2))   # 101 -> 字符串按二进制读回 45
print(int("2d", 16))      # 45

读结果:三个输出都是 45 的三种写法——数值只有一个,写法有三种。前缀只是给人和编译器的【这是几进制】的标签。

五、动手 Demo:一张换算对照表

print("十进制  二进制    十六进制")
for n in [8, 15, 16, 45, 255]:
    print(f"{n:6d}  {n:08b}  0x{n:02X}")

看到什么算成功:

十进制  二进制    十六进制
     8  00001000  0x08
    15  00001111  0x0F
    16  00010000  0x10
    45  00101101  0x2D
   255  11111111  0xFF

读结果:三行规律——15 加 1 变 16(逢十六进一在十六进制里表现为 0F 变 10);255 是一个字节能表示的最大数(8 个 1);看十六进制的每一位就能【背出】对应的四个二进制位(8=1000、D=1101)。

六、30 秒实验

打开任意 Python(或浏览器在线运行器),输入 hex(255) 和 0xFF 回车——前者返回字符串 0xff,后者直接是数值 255。同一个数,一个是【写出它的十六进制写法】,一个是【按十六进制写法读进来】——方向感立起来。

七、常见误区

  1. 【二进制是计算机发明的数学】——错。数学上任何进制都成立,二进制只是【最适合电路实现】的选择;聪明的莱布尼茨 300 年前就研究过二进制。
  2. 【十六进制是另一种数值】——错。进制只是写法,45、0b101101、0x2D 是同一个数的三件衣服。
  3. 【0x2D 里的 D 是变量】——错。A~F 在十六进制里是固定数字(10~15),不是字母变量。
自测三问(点开对答案) 1. **计算机为什么用二进制不用十进制?** 答:电路最容易做出两种稳定状态(通电/断电),十种稳定状态既难做又容易出错——二进制是工程选择不是数学必需。 2. **一个字节为什么用两位十六进制表示?** 答:2 的 4 次方等于 16,一个十六进制位恰好对应 4 个二进制位,一个字节 8 位正好拆成两半。 3. **十六进制 0xFF 等于十进制多少?** 答:15x16 + 15 = 255,也是一个字节(8 个二进制 1)能表示的最大值。

相关笔记