二进制数制是一种以二的幂为基础的位值制。每个位置都有固定权重,每个数字则说明该权重是否计入数值。掌握这条规则后,任何二进制整数的结构都可以逐位解释。
本文集中讲解位值、计数、位宽和数值范围。如果希望先了解计算机为什么使用两种状态,可以阅读什么是二进制?;如果只需要转换结果,可以直接使用二进制转十进制工具或十进制转二进制工具。
二进制数制的位值
位值制会根据数字所在的位置分配权重。十进制位置使用十的幂,二进制数制使用二的幂:
| 从右侧开始的位置 | 幂 | 位值 |
|---|---|---|
| 0 | 2⁰ | 1 |
| 1 | 2¹ | 2 |
| 2 | 2² | 4 |
| 3 | 2³ | 8 |
| 4 | 2⁴ | 16 |
| 5 | 2⁵ | 32 |
| 6 | 2⁶ | 64 |
| 7 | 2⁷ | 128 |
一个二进制数字只能是 0 或 1。1 表示计入当前位置的位值,0 表示不计入。因此,二进制数 101101 表示:
1×32 + 0×16 + 1×8 + 1×4 + 0×2 + 1×1
= 32 + 8 + 4 + 1
= 45最左侧的 1 并不是天然比其他 1 更大,而是因为它位于 2⁵ 位置。将某一位向左移动一格,其权重就会翻倍。
如何读取二进制数
从最右侧数字开始,把位置依次标为 0、1、2。将每个位置转换为二的幂,保留数字为 1 的位值,再把它们相加。
以 11001010 为例:
| 数位 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| 权重 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
| 计入数值 | 128 | 64 | 0 | 0 | 8 | 0 | 2 | 0 |
计入的位值之和为 202。写成 11001010₂ = 202₁₀ 可以明确标出基数,避免把二进制数字串误认为十进制数。你也可以用二进制转十进制工具核对,它会列出每个位置对结果的贡献。
二进制如何计数
二进制计数和十进制使用相同的进位思想。十进制的一位数字用完 0 到 9 后,从 9 进位到 10;二进制只有两个符号,所以从 1 进位到 10。
| 十进制 | 二进制 | 发生的变化 |
|---|---|---|
| 0 | 0 | 起始值 |
| 1 | 1 | 最低位设为 1 |
| 2 | 10 | 进位产生新位置 |
| 3 | 11 | 最低两个位置都为 1 |
| 4 | 100 | 末尾两个位置同时归零 |
| 5 | 101 | 位值 1 再次设为 1 |
| 6 | 110 | 加入位值 2 |
| 7 | 111 | 三个位置全部设为 1 |
| 8 | 1000 | 进位产生第四个位置 |
给一个二进制数加一时,从右向左扫描,把末尾连续的 1 改为 0,直到遇到一个 0,再将该 0 改成 1。例如 10111 + 1 = 11000。这也是二进制加法中进位规则的基础。
将十进制转换为二进制数制
一种手算方法是用非负十进制整数反复除以二,并记录每次余数,最后从下向上读取余数。
将 45 转换为二进制:
| 除法 | 商 | 余数 |
|---|---|---|
| 45 ÷ 2 | 22 | 1 |
| 22 ÷ 2 | 11 | 0 |
| 11 ÷ 2 | 5 | 1 |
| 5 ÷ 2 | 2 | 1 |
| 2 ÷ 2 | 1 | 0 |
| 1 ÷ 2 | 0 | 1 |
从下向上读取可得 101101,再按位值计算又会得到 45,可作为自检。对于很长的数值,十进制转二进制工具可以完成同样的转换,并避免精度损失。
另一种方法是逐次减去不超过目标数的最大二次幂。对于 45,先选择 32,剩 13;选择 8,剩 5;选择 4,剩 1;最后选择 1。被选中的位置写 1,未使用的位置写 0。
位宽与无符号范围
位宽表示可用的二进制位置数量。 位可以形成 种不同模式。无符号整数将所有模式用于零和正数,因此范围是 0 到 。
| 位宽 | 模式数量 | 无符号范围 |
|---|---|---|
| 4 位 | 16 | 0–15 |
| 8 位 | 256 | 0–255 |
| 16 位 | 65,536 | 0–65,535 |
| 32 位 | 4,294,967,296 | 0–4,294,967,295 |
| 64 位 | 18,446,744,073,709,551,616 | 0–18,446,744,073,709,551,615 |
最大的无符号模式始终全部由 1 构成。八位的 11111111 包含 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1,总和为 255。
前导零可以表达指定宽度,但不会改变数学值。101、0101 和 00000101 都等于十进制 5,后两种写法分别表明四位和八位格式。
有符号二进制整数
一个位模式本身无法说明有符号解释,系统还必须定义位宽和表示方法。现代计算机通常采用二进制补码。
n 位补码整数的范围是负 2 的 n 减 1 次幂,到 2 的 n 减 1 次幂再减 1。因此,八位有符号整数范围是 -128 到 127。同一个模式在不同解释下可能代表不同值:11111111 作为无符号数是 255,作为八位补码则是 -1。
在 API、文件、寄存器和编程语言类型之间传递数据时,这项区别非常重要。描述字段时应同时记录位宽以及是否有符号。
二进制小数
二进制小数点右侧的位置使用二的负整数次幂:2⁻¹ 是二分之一,2⁻² 是四分之一,2⁻³ 是八分之一。
10.101₂
= 1×2¹ + 0×2⁰ + 1×2⁻¹ + 0×2⁻² + 1×2⁻³
= 2 + 0.5 + 0.125
= 2.625₁₀有些十进制小数无法用有限个二进制小数位表示,就像三分之一在十进制中会无限循环。浮点格式只能保存有限近似值,因此软件中的简单小数运算有时也会出现舍入差异。
二进制、八进制与十六进制
八进制和十六进制可以紧凑地表示二进制分组。一个八进制数字对应三位,因为 ;一个十六进制数字对应四位,因为 。
二进制: 1101 0110
十六进制: D 6
二进制: 011 010 110
八进制: 3 2 6分组不会改变底层位模式,而且通常比先转换成十进制更快。使用二进制转十六进制工具或二进制转八进制工具,可以查看分组过程并核对结果。
常见错误
- 从左侧开始分配位值,而不是从右侧的 2⁰ 开始。
- 没有标明基数,就把
1010这样的数字串当成十进制。 - 误以为前导零会改变数学值。
- 在未说明位宽和表示方法时,直接把某个值称为有符号数。
- 认为所有十进制小数都有有限的二进制展开。
- 忽略固定宽度可能发生溢出,即使数学计算本身没有错误。
快速参考
把每条规则与二的幂联系起来,就能更容易地掌握二进制数制:
- 每向左移动一位,位值翻倍。
- 1 表示计入当前位值,0 表示不计入。
- 位可以形成 种模式。
- n 位无符号整数范围是 0 到 。
- 有符号解释必须明确位宽和表示方法。
- 三位和四位分组分别直接对应八进制和十六进制。
需要快速查数时,可以打开0 到 100 二进制表,比较各个数值、观察进位边界,并核对十进制、二进制、八进制和十六进制之间的关系。
