您可能会在不同的环境中遇到本章中介绍的三种进制数基。在某些情况下,您可能需要从一种基础转换为另一种基础。本节首先展示如何在二进制和十六进制之间进行转换,因为这两者很容易相互映射。之后,我们将探讨十进制之间的转换。

4.2.1. 二进制和十六进制之间的转换

由于二进制和十六进制的基数都是 2 的幂,因此两者之间的转换相对简单。具体来说,每个十六进制数字保存 16 个唯一值之一,四位也代表 24 = 16 个唯一值,使得它们的表达能力相当。 表 1 枚举了任何四位序列与任何单个十六进制数字之间的一对一映射。

表 1. 所有四位序列与一位十六进制数之间的对应关系

BinaryHexadecimalBinaryHexadecimal
0000010008
0001110019
001021010A
001131011B
010041100C
010151101D
011061110E
011171111F

请注意,表 1 的内容相当于简单地在两种数字系统中从 0 数到 15,因此无需记住它。有了这个映射,您可以在任一方向上转换任意数量的连续位或十六进制数字:

  • 将 0xB491 转换为二进制,只需将每个十六进制数字替换为相应的二进制值即可:
  B    4    9    1
1011 0100 1001 0001  ->  0b1011010010010001
  • 将 0b1111011001 转换为十六进制,首先将这些位从右到左分成四个块。如果最左边的块没有四位,则可以用前导零填充。然后,替换相应的十六进制值:
1111011001  ->  11 1101 1001  ->  0011 1101 1001
								  ^ padding

0011 1101 1001
  3    D    9  ->  0x3D9

4.2.2. 转换为十进制

幸运的是,将值转换为十进制是我们在本章前面的部分中一直在做的事情。给定一个以任意基数B的数字,将从右到左的系数标记为d0、d1、d2等,可以使用将值转换为十进制的通用公式:

(dN-1 × BN-1)    +    (dN-2 × BN-2)    +    …​    +    (d2 × B2)    +    (d1 × B1)    +    (d0 × B0)

4.2.3. 从十进制转换

从十进制转换为其他系统需要更多的工作。非正式地,目标是执行与上一个公式相反的操作:确定每个数字的值,以便根据数字的位置,将每一项相加得到源十进制数。以与我们描述小数位(“个”位、“十”位等)相同的方式来思考目标基本系统中的每个数字可能会有所帮助。例如,考虑从十进制转换为十六进制。十六进制数的每一位都对应于 16 的越来越大的幂,表 2 列出了前几个幂。

表 2. 16 的幂。

164163162161160
655364096256161

例如,要将 9742 转换为十六进制,请考虑:

  • 9742 可以容纳 65536 的多少倍数(换句话说,9742被65536整除商是多少)? (也就是说,“65536”这个地方的值是多少?)

    生成的十六进制值不需要任何 65536 的倍数,因为值 (9742) 小于 65536,因此 d4 应设置为 0。请注意,通过相同的逻辑,所有更高编号的数字也将为 0,因为每个数字将贡献比 65536 更大的值。到目前为止,结果仅包含:

0
164163162161160
655364096256161
d4d3d2d1d0
  • _9742 能容纳多少 4096 的倍数? (也就是说,“4096”这个地方的价值是多少?)

    4096 整除 9742 两次 (2 × 4096 = 8192),因此 d3 的值应为 2。因此,d3 将为整体值贡献 8192,因此结果仍必须占 9742 - 8192 = 1550。

02
164163162161160
655364096256161
d4d3d2d1d0
  • 1550 能容纳多少 256 的倍数? (也就是说,“256”位的值是多少?)

    256 整除 1550 六次 (6 × 256 = 1536),因此 d2 的值应为 6,剩下 1550 - 1536 = 14。

026
164163162161160
655364096256161
d4d3d2d1d0
  • 14 能容纳多少 16 的倍数? (也就是说,“十六”位的值是多少?)

    14不能被16整除,因此 d1 必须为 0。

0260
164163162161160
655364096256161
d4d3d2d1d0
  • 最后,14 能容纳多少个 1 的倍数? (换句话说,“个”位的值是多少?)

    答案当然是 14,十六进制用数字E表示。

0260E
164163162161160
655364096256161
d4d3d2d1d0

因此,十进制 9742 对应于 0x260E。

十进制转二进制:二的幂

相同的过程也适用于二进制(或任何其他数字系统),前提是您使用适当基数的幂。 表 3 列出了 2 的前几个幂,这将有助于将示例十进制值 422 转换为二进制。

表 3. 2 的幂

282726252423222120
2561286432168421

因为单个位只允许存储 0 或 1,所以转换为二进制时,问题不再是 “不同层级指数的基数能整除的商(系数)?”。相反,问一个更简单的问题:“2 的下一次幂(指数)能整除吗?” 例如,在转换 422 时:

  • 256 整除 422,因此 d8 应为 1。剩下 422 - 256 = 166。
  • 128 整除 166,所以 d7 应该是 1。剩下 166 - 128 = 38。
  • 64 无法整除 38,因此 d6 应为 0。
  • 32 整除 38,所以 d5 应该是 1。剩下 38 - 32 = 6。
  • 16 无法整除 6,因此 d4 应为 0。
  • 8 无法整除 6,因此 d3 应为 0。
  • 4 整除 6,所以 d2 应该是 1。剩下 6 - 4 = 2。
  • 2 适合 2,因此 d1 应为 1。这样就剩下 2 - 2 = 0。(注意:达到 0 后,所有剩余数字将始终为 0。)
  • 1 无法整除 0,因此 d0 应为 0。

因此,十进制 422 对应于 0b110100110。

十进制转二进制:重复除法(辗转相除法)

我们刚刚描述的方法通常对于熟悉 2 的相关幂的学生来说效果很好(例如,对于 422,转换器必须认识到它应该从 d8 开始,因为
= 512 太大)。

另一种方法不需要知道二的幂。相反,此方法通过检查十进制数的奇偶校验(偶数或奇数)状态并重复将其除以二(向下四舍五入)以确定每个连续位来构建二进制结果。请注意,它从_右到左_构建结果位序列。如果十进制值为偶数,则下一位应为零;如果是奇数,下一位应该是 1。当除法达到零时,转换完成。

例如,转换 422 时:

  • 422 是偶数,因此 d0 应为 0。(这是最右边的位。)
  • 422 / 2 = 211,这是奇数,因此 d1 应为 1。
  • 211 / 2 = 105,这是奇数,因此 d2 应为 1。
  • 105 / 2 = 52,是偶数,因此 d3 应为 0。
  • 52 / 2 = 26,是偶数,因此 d4 应为 0。
  • 26 / 2 = 13,这是奇数,因此 d5 应为 1。
  • 13 / 2 = 6,是偶数,因此 d6 应为 0。
  • 6 / 2 = 3,这是奇数,因此 d7 应为 1。
  • 3 / 2 = 1,这是奇数,因此 d8 应为 1。
  • 1 / 2 = 0,因此任何编号为 9 或以上的数字都将为 0,并且算法终止。

正如预期的那样,此方法生成相同的二进制序列:0b110100110。