报错信息里的 0xFF、CSS 里的 #1e90ff、IP 地址 192.168.1.1——它们底层都是同一件事:进制。这篇不背口诀,用几个实例把换算逻辑讲透,看完能直接上手算。
十进制的 3705 = 3×1000 + 7×100 + 0×10 + 5×1,每一位的「权值」是 10 的幂。把 10 换成其他数字就是其他进制:二进制每位的权值是 1、2、4、8……,十六进制是 1、16、256……
例:二进制 1010 = 1×8 + 0×4 + 1×2 + 0×1 = 10;十六进制 0xFF = 15×16 + 15×1 = 255。十六进制缺 6 个数字,就用 a–f 表示 10–15,所以 F 就是 15。
这是最常用的转换,因为 2⁴ = 16,每 4 个二进制位恰好对应 1 个十六进制位。把二进制从右往左每 4 位分组,每组独立换算:
11110101 → 1111 | 0101 → F | 5 → 0xF5。反方向同理,每位十六进制展开成 4 位二进制即可。这解释了为什么内存、颜色值、MAC 地址都用十六进制书写——它就是二进制的紧凑写法,一位顶四位。
| 前缀 | 进制 | 例子 |
|---|---|---|
| 0x 或 # | 十六进制 | 0x1F,#1e90ff |
| 0b | 二进制 | 0b1010 |
| 0o | 八进制 | 0o755 |
| 无前缀 | 十进制(默认) | 255 |
看到数字先看前缀再读值,否则 0x10(=16)和 10 会差出一倍。#1e90ff 这类颜色值实际是三组十六进制:R=1e(30)、G=90(144)、B=ff(255)。
把十进制数不断除以 2,记下每轮余数,最后把余数倒着写。以 13 为例:13÷2=6 余 1,6÷2=3 余 0,3÷2=1 余 1,1÷2=0 余 1。从下往上读余数:1101。验证:8+4+0+1=13 ✓。这个方法对任意进制通用——转八进制就除 8 取余,转十六进制就除 16 取余(余数 10–15 写成 A–F)。
小数部分则是反过来「乘基取整」:0.625×2=1.2 取 1,0.2×2=0.4 取 0,0.4×2=0.8 取 0……所以 0.625 的二进制是 0.101。绝大多数十进制小数在二进制下是无限循环小数,这就是浮点误差的根源,也是金融计算建议用整数(分)或定点数的原因。
回头看报错信息和配置文件:Linux 文件权限 755 是八进制(三位各代表一类用户)、Python 字面量 0x10 是十六进制、正则里的 \x41 是字符 A 的十六进制编码。它们出现的原因都一样——字节才是数据的真相,十六进制是字节最紧凑的人类可读形式。一个字节恰好两位十六进制,看 0xE4 0xB8 0xAD 三个字节就知道是三个字节的数据,比十进制 228 180 173 直观得多。掌握进制不是要你心算如飞,而是看到这些数字时能反推出「底层存的是什么」,排查乱码、溢出、权限问题时不慌。
问:负数在二进制里怎么表示?
计算机用「补码」:最高位是符号位,取反加一。8 位下的 -1 是 11111111,这解释了很多语言里无符号/有符号溢出的诡异表现。
问:为什么 0.1 + 0.2 不等于 0.3?
十进制 0.1 转成二进制是无限循环小数,浮点数只能截断存储,误差累计后就是你看到的那 0.0000000000000001。