1. 引言
进制转换是计算机科学中最基础也最重要的概念之一。无论是理解内存中的二进制数据、编写底层驱动,还是处理网络协议中的十六进制报文,都离不开进制转换。本文将从原理出发,系统讲解二进制、八进制、十进制和十六进制之间的转换方法,并给出可复制的代码示例。
2. 进制的核心概念
进制(Number System)是用一组固定符号表示数值的计数方式。日常生活中我们最熟悉的是十进制,而计算机内部则使用二进制。理解进制的关键在于两个要素:基数和位权。
- 基数(Base):该进制使用的符号个数。二进制的基数是 2,八进制是 8,十进制是 10,十六进制是 16。
- 位权(Weight):每一位数字所代表的实际数值,等于该位数字乘以基数的幂次。例如十进制数 123 中,1 的位权是 10 的 2 次方,即 100。
下表总结了常见进制的基数、符号范围和典型用途:
| 进制 | 基数 | 符号范围 | 典型用途 |
|---|---|---|---|
| 二进制 | 2 | 0、1 | 计算机底层存储、位运算 |
| 八进制 | 8 | 0 到 7 | Unix 文件权限、早期系统 |
| 十进制 | 10 | 0 到 9 | 日常计数、人类交互 |
| 十六进制 | 16 | 0 到 9、A 到 F | 内存地址、颜色值、网络报文 |
3. 十进制转其他进制
十进制转其他进制最常用的方法是除基取余法。以十进制数 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 的二进制表示。同理,十进制转八进制或十六进制时,只需把除数换成 8 或 16 即可。
4. 其他进制转十进制
其他进制转十进制使用按权展开求和法。将每一位数字乘以对应的位权,再求和即可。例如二进制数 101101 转十进制:
1×2^5 + 0×2^4 + 1×2^3 + 1×2^2 + 0×2^1 + 1×2^0 = 32 + 0 + 8 + 4 + 0 + 1 = 45十六进制数 2F 转十进制:2×16^1 + 15×16^0 = 32 + 15 = 47。注意十六进制中 F 代表数值 15。
5. 二进制与八进制、十六进制的快速转换
由于 8 是 2 的三次方,16 是 2 的四次方,二进制与八进制、十六进制之间存在非常便捷的对应关系,无需经过十进制中转。
二进制转八进制:从右往左每 3 位一组,不足 3 位时在左侧补 0,每组直接转换为对应的八进制数字。
101101 → 101 101 → 5 5 → 八进制 55二进制转十六进制:从右往左每 4 位一组,不足 4 位时在左侧补 0,每组转换为对应的十六进制数字。
101101 → 0010 1101 → 2 D → 十六进制 2D反向转换同样简单:把八进制或十六进制的每一位数字展开为对应的 3 位或 4 位二进制即可。
6. 代码实战
下面给出 C 语言中输出 0 到 7 二进制值的示例,使用位运算逐位打印每一位:
#include <stdio.h> void printBinary(int n) { // 从高位到低位逐位输出 for (int i = 2; i >= 0; i--) { printf("%d", (n >> i) & 1); } } int main() { printf("十进制 0 到 7 的二进制值:\n"); for (int i = 0; i <= 7; i++) { printf("%d → ", i); printBinary(i); printf("\n"); } return 0; }运行结果如下:
十进制 0 到 7 的二进制值: 0 → 000 1 → 001 2 → 010 3 → 011 4 → 100 5 → 101 6 → 110 7 → 1117.进制转换十进制转二进制算数方法
81转二进制结果如下
整数 结果 为1010001
例:小数0.65转二进制结果如下
小数 结果 为10100
8. 常见陷阱与注意事项
- 大小写问题:十六进制中的字母 A 到 F 不区分大小写,但解析时需确保字符串合法。
- 负数处理:
Integer.toBinaryString对负数返回的是补码形式,与正数的转换结果不同,需要特别注意。 - 溢出风险:
Integer.parseInt只能处理 32 位范围内的数值,超出范围应使用Long或BigInteger。 - 前导零:转换结果默认不保留前导零,若需要固定位数展示,可自行补零。
9. 总结
进制转换的本质是理解基数与位权的关系。十进制转其他进制用除基取余法,其他进制转十进制用按权展开求和法,而二进制与八进制、十六进制之间则可以通过分组快速转换。掌握这些方法后,无论是阅读底层代码还是调试网络协议,都会更加得心应手。