1 整数进制
在计算机科学中,数据的底层存储与运算均基于二进制系统。无论是简单的数值、字符,还是复杂的多媒体信息(如图像、音频和视频),在计算机内部的底层存储层面,最终都会被编码为二进制(Binary)形式进行表示与操作。
然而,二进制表示法通常非常长。对于人类开发者而言,直接阅读和书写大量连续的 0 与 1 既不直观,也极易出错。为了更方便地观察和操作底层的二进制数据,计算机科学中引入了八进制(Octal)和十六进制(Hexadecimal)。这两种进制作为二进制的紧凑表示形式,通常被称为二进制的 “简写”,能够显著提高二进制数据的可读性。
1.1 常见进制系统
理解不同进制系统的核心在于掌握其基数(Base)与进位规则。基数决定了该进制中每一位允许使用的数字符号数量。
- 二进制(Base-2):使用数字 0 和 1 表示数值。在二进制中,每一位的基数为 2,当某一位的值达到 2 时,便向高位进位,即“逢二进一”。这是计算机内部存储和处理数据的基本方式。
- 八进制(Base-8):使用数字 0 到 7 表示数值。在八进制中,每一位的基数为 8,当某一位的值达到 8 时,便向高位进位,即“逢八进一”。这是一种早期用于简化二进制表示的进位制,在现代开发中主要用于文件权限设置等特定场景。
- 十进制(Base-10):使用数字 0 到 9 表示数值。在十进制中,每一位的基数为 10,当某一位的值达到 10 时,便向高位进位,即“逢十进一”。这是人类日常生活中最广泛使用的计数系统,也是代码中整数默认的输入与输出形式。
- 十六进制(Base-16):使用数字 0 到 9 以及字母 A 到 F(或 a 到 f)表示数值,其中 A - F 分别对应十进制的 10 - 15。在十六进制中,每一位的基数为 16,当某一位的值达到 16 时,便向高位进位,即“逢十六进一”。这是目前最常用的人类可读二进制简写形式,广泛应用于内存地址、颜色编码和调试信息中。
下表展示了十进制数值 0 到 17 在这四种进制下的对应写法:
| 二进制 | 八进制 | 十进制 | 十六进制 |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 |
| 10 | 2 | 2 | 2 |
| 11 | 3 | 3 | 3 |
| 100 | 4 | 4 | 4 |
| 101 | 5 | 5 | 5 |
| 110 | 6 | 6 | 6 |
| 111 | 7 | 7 | 7 |
| 1000 | 10 | 8 | 8 |
| 1001 | 11 | 9 | 9 |
| 1010 | 12 | 10 | A |
| 1011 | 13 | 11 | B |
| 1100 | 14 | 12 | C |
| 1101 | 15 | 13 | D |
| 1110 | 16 | 14 | E |
| 1111 | 17 | 15 | F |
| 10000 | 20 | 16 | 10 |
| 10001 | 21 | 17 | 11 |
相比二进制,八进制与十六进制使用更少的位数表达相同的数值,从而显著降低了人工阅读与书写的负担。
1.2 进制的前缀表示
在 Python 程序中,整数常量可以通过特定的前缀(Prefix)来表示其所属的进制。前缀不仅帮助开发者清晰地表达意图,也是 Python 解释器正确解析字面量数值的依据。具体规则如下:
- 二进制(Binary):必须使用0b或0B开头,后跟由 0 和 1 组成的数字序列。注意,前缀第一位是数字 0,第二位是英文小写或大写字母 b。例如,0b1010 表示十进制的 10。
- 八进制(Octal):必须使用0o或0O开头,后跟 0 到 7 的数字。注意,前缀第一位是数字 0,第二位是英文小写或大写字母 o。例如,0o12 表示十进制的 10。
- 十进制(Decimal):直接书写数字,不带任何前缀。例如,10 表示十进制的 10。
- 十六进制(Hexadecimal):必须使用0x或0X开头,后跟 0 - 9 和 A - F(或 a - f)。例如,0xA 表示十进制的 10。
以下示例程序演示了上述四种前缀在 Python 代码中的具体写法:
# 15_integer_literal.py # 十进制(无前缀) dec = 10 # 二进制(0b 前缀) binary_num = 0b1010 # 八进制(0o 前缀) octal_num = 0o12 # 十六进制(0x 前缀) hex_num = 0xA # print() 函数默认以十进制形式输出整数值 print(dec) # 输出:10 print(binary_num) # 输出:10 print(octal_num) # 输出:10 print(hex_num) # 输出:10程序运行结果如下所示:
print() 函数默认以十进制形式输出整数值,因此无论使用哪种进制书写整数常量,输出结果均显示为对应的十进制数值。
1.3 内置进制转换函数
在实际开发中,你可能需要将一个整数转换为其他进制的字符串表示形式,以便进行调试、日志记录或底层数据分析。Python 提供了三个内置函数(Built-in Functions)来直接完成这一任务,你无需实现具体的转换算法,直接调用即可:
- bin(整数):返回该整数的二进制字符串,结果以 0b 开头。
- oct(整数):返回该整数的八进制字符串,结果以 0o 开头。
- hex(整数):返回该整数的十六进制字符串,结果以 0x 开头。
以下代码展示了上述函数的用法及其输出特征:
# 16_base_conversion.py dec = 10 print("二进制表示:", bin(dec)) # 输出:0b1010 print("八进制表示:", oct(dec)) # 输出:0o12 print("十六进制表示:", hex(dec)) # 输出:0xa程序运行结果如下所示:
这三个函数均返回字符串类型,且各自保留了对应进制的前缀标识。
2 进制转换
掌握不同进制之间的人工转换方法,有助于你加深对进制系统内在规律的理解,并为后续学习位运算奠定基础。本节将系统讲解整数在二进制、八进制、十进制与十六进制之间的双向转换方法。
2.1 转换方法的两种通用逻辑
在进入具体示例之前,先理解两种最核心的转换方法。这两种方法适用于十进制与任意其他进制之间的相互转换。
按权展开法(其他进制 → 十进制)
核心思路:任何一个多位数,其每一位都有一个对应的 “权值”,该权值由进制基数与位置共同决定。将每一位数字与该位的权值相乘,再累加求和,即可得到该数在十进制下的数值。
为了更好地理解,先看一个熟悉的十进制例子:数字123实际上表示1 × 10² + 2 × 10¹ + 3 × 10⁰。即从最低位开始,每一位乘以 10 的递增次方后相加。
对于任意进制,只需将上式中的基数 10 替换为目标进制基数即可:
- 二进制 → 十进制:基数替换为 2。
- 八进制 → 十进制:基数替换为 8。
- 十六进制 → 十进制:基数替换为 16。
通用规则:从最低位开始,将每一位数字乘以对应基数的递增次方(从 0 次方开始),然后求和。
除基取余法(十进制 → 其他进制)
核心思路:将一个十进制数反复除以目标进制基数,每次记录余数。当商为 0 时停止,最后将所有余数从最后一次除法所得余数到第一次所得余数逆序排列,即为目标进制数。
通用规则:
- 将十进制数除以目标基数,记录商和余数。
- 用商继续除以目标基数,再次记录商和余数。
- 重复上述步骤,直到商为 0。
- 将所有余数逆序排列。
对于不同目标进制,仅需替换步骤中的基数即可:
- 十进制 → 二进制:基数替换为 2。
- 十进制 → 八进制:基数替换为 8。
- 十进制 → 十六进制:基数替换为 16。
💡 提示:十六进制中的字母替换
使用除基取余法转换为十六进制时,若余数大于 9,须使用字母 A – F 或 a – f(分别对应 10 – 15)表示该余数。
2.2 方法应用示例
以下分别展示按权展开法与除基取余法在三种进制中的具体应用。
按权展开法应用
示例 1(二进制 → 十进制):将二进制数 1011 转换为十进制数。
步骤: 第 0 位:1 × 2⁰ = 1 第 1 位:1 × 2¹ = 2 第 2 位:0 × 2² = 0 第 3 位:1 × 2³ = 8 求和:1 + 2 + 0 + 8 = 11 结果:1011₂ = 11₁₀示例 2(八进制 → 十进制):将八进制数 101 转换为十进制数。
步骤: 第 0 位:1 × 8⁰ = 1 第 1 位:0 × 8¹ = 0 第 2 位:1 × 8² = 64 求和:1 + 0 + 64 = 65 结果:101₈ = 65₁₀示例 3(十六进制 → 十进制):将十六进制数 34A 转换为十进制数。
步骤: 第 0 位:A = 10,10 × 16⁰ = 10 第 1 位:4 × 16¹ = 64 第 2 位:3 × 16² = 768 求和:10 + 64 + 768 = 842 结果:34A₁₆ = 842₁₀除基取余法应用
示例 1(十进制 → 二进制):将十进制数 56 转换为二进制数。
步骤: 56 ÷ 2 = 28 余 0 28 ÷ 2 = 14 余 0 14 ÷ 2 = 7 余 0 7 ÷ 2 = 3 余 1 3 ÷ 2 = 1 余 1 1 ÷ 2 = 0 余 1 逆序读取余数:111000 结果:56₁₀ = 111000₂示例 2(十进制 → 八进制):将十进制数 156 转换为八进制数。
步骤: 156 ÷ 8 = 19 余 4 19 ÷ 8 = 2 余 3 2 ÷ 8 = 0 余 2 逆序读取余数:234 结果:156₁₀ = 234₈示例 3(十进制 → 十六进制):将十进制数 356 转换为十六进制数。
步骤: 356 ÷ 16 = 22 余 4 22 ÷ 16 = 1 余 6 1 ÷ 16 = 0 余 1 逆序读取余数:164 结果:356₁₀ = 164₁₆2.3 二进制与八进制、十六进制之间的转换
由于8 = 2³且16 = 2⁴,二进制与八进制、十六进制之间存在更快速的转换方式 —— 直接对二进制位进行分组,而非通过十进制作为中间桥梁。
二进制 ↔ 八进制
二进制 → 八进制
转换方法(取三合一法):从二进制数的最低位起,每三位分为一组(最高位不足三位时在左侧补零),将每组三位二进制数转换为一位八进制数字(0 – 7),然后从左到右组合。
示例:将二进制数 1101011 转换为八进制数。
步骤: 从最低位每三位分组:1 | 101 | 011 最高位补零:001 | 101 | 011 逐组转换: 001 → 1 101 → 5 011 → 3 组合:153 结果:1101011₂ = 153₈八进制 → 二进制
转换方法(取一分三法):将八进制数的每一位数字,分别转换为对应的三位二进制数,然后按原顺序组合。最终结果最左侧的多余零可以省略。
示例:将八进制数 153 转换为二进制数。
步骤: 逐位转换: 1 → 001 5 → 101 3 → 011 组合:001101011 省略前导零:1101011 结果:153₈ = 1101011₂二进制 ↔ 十六进制
二进制 → 十六进制
转换方法(取四合一法):从二进制数的最低位起,每四位分为一组(最高位不足四位时在左侧补零),将每组四位二进制数转换为一位十六进制数字(0 – F),然后从左到右组合。
示例:将二进制数 1001011 转换为十六进制数。
步骤: 从最低位每四位分组:100 | 1011 最高位补零:0100 | 1011 逐组转换: 0100 → 4 1011 → B 组合:4B 结果:1001011₂ = 4B₁₆十六进制 → 二进制
转换方法(取一分四法):将十六进制数的每一位数字(含 A – F),分别转换为对应的四位二进制数,然后按原顺序组合。最终结果最左侧的多余零可以省略。
示例:将十六进制数 23B 转换为二进制数。
步骤: 逐位转换: 2 → 0010 3 → 0011 B → 1011 组合:001000111011 省略前导零:1000111011 结果:23B₁₆ = 1000111011₂八进制 ↔ 十六进制
八进制与十六进制之间没有直接的转换方法。若需要在两者之间进行转换,可借助二进制作为中间桥梁。
八进制 → 十六进制
转换路径:先将八进制数转换为二进制(取一分三法),再将得到的二进制数转换为十六进制(取四合一法)。
示例:将八进制数 153 转换为十六进制数。
步骤: 1. 先将 153₈ 转为二进制(取一分三法): 1 → 001 5 → 101 3 → 011 组合:001101011 省略前导零:1101011 2. 再将 1101011₂ 转为十六进制(取四合一法): 从最低位每四位分组:110 | 1011 最高位补零:0110 | 1011 逐组转换: 0110 → 6 1011 → B 组合:6B 结果:153₈ = 6B₁₆十六进制 → 八进制
转换路径:先将十六进制数转换为二进制(取一分四法),再将得到的二进制数转换为八进制(取三合一法)。
示例:将十六进制数 6B 转换为八进制数。
步骤: 1. 先将 6B₁₆ 转为二进制(取一分四法): 6 → 0110 B → 1011 组合:01101011 省略前导零:1101011 2. 再将 1101011₂ 转为八进制(取三合一法): 从最低位每三位分组:1 | 101 | 011 最高位补零:001 | 101 | 011 逐组转换: 001 → 1 101 → 5 011 → 3 组合:153 结果:6B₁₆ = 153₈📚 扩展:选择最适合的转换路径
从上述示例可以看出,八进制与十六进制之间的转换本质上是前文已学方法的组合运用。在实际计算中,你也可以先将原数转为十进制,再转到目标进制。两种路径的结果一致,你可以根据个人习惯选择最适合的计算方式。
3 小数与进制转换
第 2 章所讲解的进制转换方法均针对整数。当数值包含小数部分时,转换规则需要做相应扩展。本节简要介绍小数在常见进制之间的转换方法。
小数的进制转换在原理上与整数一致,均基于 “按权展开” 与 “基数乘除” 的核心思想,区别在于小数部分使用负指数作为位权。
3.1 其他进制小数转换为十进制小数
转换方法:采用按权展开法。与整数部分类似,但小数部分的位权从小数点后第一位开始,分别为基数的 -1、-2、-3 …… 次方。将每一位数字与对应的位权相乘,然后累加求和。
示例:将二进制小数 0.101 转换为十进制小数。
步骤: 第 -1 位(小数点后第 1 位):1 × 2⁻¹ = 0.5 第 -2 位(小数点后第 2 位):0 × 2⁻² = 0 第 -3 位(小数点后第 3 位):1 × 2⁻³ = 0.125 求和:0.5 + 0 + 0.125 = 0.625 结果:0.101₂ = 0.625₁₀该规则适用于任意进制的小数转换为十进制。当被转换的小数来自八进制时,将公式中的基数 2 替换为 8;来自十六进制时,替换为 16。
3.2 十进制小数转换为其他进制小数
转换方法:采用乘基取整、顺序排列法。
- 将十进制小数部分乘以目标基数,记录乘积的整数部分。
- 用上一步乘积的小数部分继续乘以目标基数,再次记录整数部分。
- 重复上述步骤,直到小数部分为 0,或达到所需的精度。
- 将所有记录的整数按从上到下的顺序排列。
示例:将十进制小数 0.8125 转换为二进制小数。
步骤: 0.8125 × 2 = 1.625 → 整数部分为 1,剩余小数部分为 0.625 0.625 × 2 = 1.25 → 整数部分为 1,剩余小数部分为 0.25 0.25 × 2 = 0.5 → 整数部分为 0,剩余小数部分为 0.5 0.5 × 2 = 1.0 → 整数部分为 1,剩余小数部分为 0(结束) 顺序读取整数部分:1101 结果:0.8125₁₀ = 0.1101₂该规则的核心逻辑保持不变。应用于其他进制时,仅需将乘以的基数 2 替换为目标进制基数(如转换为八进制时乘以 8,转换为十六进制时乘以 16),并按该进制的进位规则记录整数部分。
3.3 混合数的处理
对于同时包含整数部分和小数部分的数(如 12.625),应将整数部分和小数部分拆开,分别进行转换,最后将两部分结果合并,小数点位置保持不变。
至于整数部分与小数部分各自采用何种转换方法,取决于具体的转换方向:
- 其他进制 → 十进制:整数部分与小数部分均使用 “按权展开法”。
- 十进制 → 其他进制:整数部分使用 “除基取余、逆序排列法”,小数部分使用 “乘基取整、顺序排列法”。
示例:将十进制数 12.625 转换为二进制数。
整数部分转换(除基取余法): 12 ÷ 2 = 6 余 0 6 ÷ 2 = 3 余 0 3 ÷ 2 = 1 余 1 1 ÷ 2 = 0 余 1 逆序读取:1100 小数部分转换(乘基取整法): 0.625 × 2 = 1.25 → 整数部分为 1,剩余小数部分为 0.25 0.25 × 2 = 0.5 → 整数部分为 0,剩余小数部分为 0.5 0.5 × 2 = 1.0 → 整数部分为 1,剩余小数部分为 0(结束) 顺序读取:101 合并结果:12.625₁₀ = 1100.101₂该示例展示了混合数的完整转换流程。实际应用中,你只需根据转换方向选择对应的方法即可。
3.4 精度问题
需要特别注意的是,并非所有十进制小数都能被其他进制精确表示。某些十进制小数在转换为二进制(或其他进制)时,会产生无限循环小数。
例如,十进制小数 0.1 转换为二进制时,会得到一个无限循环的二进制小数:
0.1₁₀ = 0.00011001100110011...₂由于计算机存储空间的限制,无限循环小数无法被完整存储,只能截断至有限位数进行近似表示。这便是浮点数运算中精度误差的根本来源。
📚 扩展:精度问题与编程实践
十进制小数转换为二进制时产生的无限循环现象,是浮点数精度问题的根源。例如,在 Python 中执行 0.1 + 0.2,得到的结果并非精确的 0.3,而是一个近似值 0.30000000000000004。这是由于 0.1 和 0.2 在计算机内部均为近似存储所致。有关浮点数及其精度问题的深入讨论,将在后续章节中展开。此处仅作为进制转换知识的延伸了解即可。
4 进制转换工具
手动进行进制转换是理解进制系统内在规律的重要途径。然而,当数值较大或需要频繁转换时,手动计算容易出错且效率较低。此时可以借助工具快速完成转换,并对人工计算结果进行验证。
本节介绍两种常用的进制转换工具:Windows 系统自带的计算器与在线进制转换工具。
4.1 Windows 计算器(程序员模式)
Windows 系统自带的计算器提供了 “程序员模式”(Programmer Mode),支持二进制、八进制、十进制与十六进制之间的快速转换。操作方法如下:
- 打开计算器:按下Win键,在搜索栏中输入 “计算器”,然后点击打开程序。
- 切换为程序员模式:点击计算器左上角的≡菜单图标,选择 “程序员” 模式。
- 输入数据并查看结果:在对应进制的输入框中输入数值,其他进制区域将自动显示转换后的结果。
该工具支持整数在四种常见进制之间的双向转换,并提供了数据宽度控制功能(按钮显示为 BYTE、WORD、DWORD、QWORD,分别对应 8 位、16 位、32 位和 64 位),可用于在调试或阅读底层代码时快速查看数值的进制表示。
4.2 在线进制转换工具
Windows 计算器的程序员模式虽然便捷,但也存在两个主要限制:不支持小数(浮点数)的转换,且仅支持四种常见进制。
如果你需要处理第 3 章中提到的小数进制转换,或进行更大范围的进制转换(如 32 进制、36 进制),在线进制转换工具是更优的选择。其主要优势包括:
- 支持范围广:支持 2 至 36 进制之间的任意转换。
- 支持小数:能够处理浮点数,可用于验证第 3 章 “乘基取整法” 的计算结果。
- 跨平台:无需安装且跨平台,有浏览器即可使用,对 macOS 和 Linux 用户同样友好。
例如,OSCHINA 工具箱(https://tool.oschina.net/hexconvert)是一个广受开发者欢迎的在线工具,支持 2 至 36 进制之间的任意转换,也支持浮点数。
💡 提示:工具的辅助定位
进制转换工具主要用于快速获取结果或验证手算答案。建议你在学习阶段先尝试手动计算,再使用工具进行核对。这样才能真正掌握进制转换的内在规律,而非仅仅依赖工具输出结果。