☰
进制转换全解析:从二进制到十六进制的原理、方法与实战应用
2026/10/9 10:40:35 网站建设 项目流程

进制这个词,看着像是个只存在于课本里的数学概念,但只要你和计算机沾过边,其实早就在和它打交道了。调试程序时看到的一串串 0x 开头地址,类 Unix 系统里文件权限那三位 755 数字,网页配色板里的 #FF5733,硬件层面电平高低代表的 0 和 1——这些背后全是进制。所以我决定把这个基础话题完完整整讲一遍:二进制、八进制、十进制、十六进制,从它们各自的来头,到相互转换的标准方法,再到实际开发中怎么用、哪些地方容易错。

这篇文章适合两类人。一类是刚接触计算机、想系统打牢基础的初学者;另一类是工作了一段时间、遇到进制相关内容还是靠计算器救场的开发者。我会尽量把原理讲透、把步骤拆细,并把自己踩过的一些坑直接放在明处,让你少走弯路。

1. 四种进制是怎么来的:从数手指到机器语言的必然

1.1 进制的本质:一套符号加一条进位规则

所谓进制,说白了就是一套"数到几就要进位"的计数规则。我们最熟悉的十进制,用到 0 到 9 十个数字符号,每数满十个就往高位进一位,所以 9 的下一个不是发明一个新符号,而是写成 10——这里的 1 代表一个"十",0 代表没有额外的"个"。这个逻辑放到任何进制都成立:二进制只有 0 和 1,所以 1 再往上就是 10(这里读作"一零",不是"十");八进制有 0 到 7 八个符号,7 的后一位同样写成 10;十六进制有十六个符号,F 的后一位也写成 10。

很多初学者在这里会钻牛角尖:为什么二进制里的 10 等于十进制里的 2?原因在于 "10" 只是一种记号,它到底代表多大,取决于这个进制的基数。二进制里每一位的权值是 2 的幂,"10" 就是 1×2¹+0×2⁰=2;八进制里权值是 8 的幂,"10" 就是 8;十六进制里则是 16。同一个写法在不同进制下数值完全不同,理解这一点,后面的所有转换方法就不再是死记硬背,而是一套可以当场推导的规则。

1.2 十进制是习惯,二进制是必然,另外两种是折中

从人类角度说,我们习惯十进制,大概率只是因为有十根手指,数起来方便。计算机用二进制则完全是工程上的必然选择:硬件最容易实现的就是一个稳定可区分的两种状态,比如电压高和电压低、开关的通断、磁极的正反。如果让电路去稳定区分十种电平,噪声容限和器件复杂度都会急剧上升,所以从最底层开始,计算机的"母语"就是二进制,所有指令、数据最终都要落到 0 和 1 上。

那八进制和十六进制存在的意义是什么?它们既不是人类的天然习惯,也不是机器的底层语言,而是人和二进制之间的翻译工具。二进制对硬件友好,对人类的肉眼却极不友好:十进制数 47 写成二进制是 101111,六个字符还能忍,换成 1024 就成了 10000000000,十一个字符,再大一点眼睛直接看花。而 2³=8、2⁴=16,意味着一位八进制数恰好对应三位二进制数,一位十六进制数恰好对应四位二进制数。用这种分组缩写的方式,长串二进制瞬间能压缩到四分之一甚至更短,而且转换过程完全没有误差。这就是工程师们把八进制和十六进制"请"出来的根本原因。

1.3 四种进制的基本参数总览

先给一张总览表,后面的讲解都围绕它展开:

进制基数可用符号进位规则示例写法
二进制20、1逢二进一101101₂
八进制80~7逢八进一55₈
十进制100~9逢十进一45₁₀
十六进制160~9、A~F逢十六进一2D₁₆

注意我写的下标 2、8、10、16,是用来标注进制的角标;实际工程里更常看到的是前缀表示法,比如 0b101101、0o55、0x2D,不同语言写法略有差异,但意思完全一致。不管是角标还是前缀,目的都是消除歧义:同样是 101101,如果不标注进制,谁也不知道它代表什么;加上标记,才是一串可以被准确解读的数。另外值得特别注意的是,十六进制用 A~F 补足了十到十五这几个符号,这也是它初学时最容易让人困惑的地方。

2. 四种进制逐个拆解:每一位到底值多少钱

2.1 十进制:先拆开看它内部怎么运作

十进制简单到我们从不思考它,但它是理解其他进制的最佳参照物。拿 47 来说,它由十位上的 4 和个位上的 7 组成,按权展开是 4×10¹ + 7×10⁰ = 40 + 7 = 47。这里的 10¹、10⁰ 就是各位的位权:整数部分从右往左依次是 10⁰、10¹、10²、10³……也就是 1、10、100、1000……小数部分则是 10⁻¹、10⁻²、10⁻³……47.25 就是 4×10¹ + 7×10⁰ + 2×10⁻¹ + 5×10⁻²。这套"按权展开求和"的思维方式是整个进制转换的发动机,把它想明白了,二进制、八进制、十六进制不过是把 10 换成了 2、8、16 而已。

2.2 二进制:位权重是翻倍增长的

二进制的结构跟十进制完全平行,只是位权从 10 的幂换成 2 的幂:整数部分从右往左是 2⁰=1、2¹=2、2²=4、2³=8、2⁴=16、2⁵=32……所以 1011 按权展开就是 1×2³ + 0×2² + 1×2¹ + 1×2⁰ = 8+0+2+1 = 11。我后来熟练了才发现,二进制转十进制根本不用逐位乘,只看哪些位置是 1,把对应的 2 的幂加起来就行。比如 100101,脑子里就是 32+4+1=37,又快又稳。

二进制的一位叫 bit,八位叫 byte,四位叫 nibble。这些名词不是考概念用的,它们和十六进制有直接关系:一个字节正好八位,而四位二进制对应一位十六进制,所以一个字节恰好能写成两个十六进制字符——1111 1111 写成 FF,1000 0000 写成 80。做过底层开发的人都会感激这种对应关系,因为它让二进制和十六进制之间的换算变成了一种视觉直觉。

2.3 八进制:三位并成一位的紧凑工具

八进制用 0 到 7 八个符号,位权是 8 的幂:8⁰=1、8¹=8、8²=64、8³=512……八进制数 55 按权展开是 5×8¹ + 5×8⁰ = 40+5 = 45。这里要注意,55 读作"五五"而不是"五十五",因为在八进制里根本没有"十"这个数,它只是两个符号的排列。

八进制最漂亮的地方在于 2³=8,一位八进制数恰好能表示三位二进制的全部组合(000 到 111)。这个特性让它天然适合做二进制的紧凑表达,在计算机早期非常流行。现在八进制在应用层的存在感低了不少,但类 Unix 系统的文件权限仍然坚持用它:chmod 755 里的 755 就是八进制数,每一位由三个权限位组合而来。只要类 Unix 的文件权限体系还在一天,八进制就不会消失。

2.4 十六进制:最适合做二进制速记的写法

十六进制需要十六个符号,阿拉伯数字不够用,于是借了字母 A 到 F 表示十到十五。初学者最容易在这里懵:为什么 9 的后面不是 10 而是 A?因为十六进制的一位只能容纳 0 到 15 共十六个值,9 之后数字符号已经用完,只能拿字母顶上。所以 2F 里的 F 代表 15,按权展开是 2×16¹ + 15×16⁰ = 32+15 = 47。

十六进制的位权是 16 的幂:16⁰=1、16¹=16、16²=256、16³=4096……递增非常快,所以同样的数值写出来特别短。调试器里的地址 0x7ffe 如果转成二进制是 0111 1111 1111 1110,肉眼完全没法读,但用十六进制只要四个字符。因为和二进制是四位对一位的无损映射,十六进制成了底层开发、网络协议、调试信息中的通用语言,几乎所有跟硬件沾边的文档都会优先用十六进制贴数据。

2.5 权值:串起四种进制的核心线索

看完四种进制,你会发现所有差异都浓缩在一个词上:位权。同一个符号 1,放在二进制最高位可能值成千上万,放在最低位就是 1;同一个符号 A,在十六进制里代表 10,可一旦放到别的进制它根本不是合法符号。所谓进制转换,本质就是把一种"书写方式"下的数,按位权展开、重新组织为另一种"书写方式"。所以我的建议是,不要背太多的口诀和表格,把"数字 × 位权求和"这个核心公式反复用熟,任何转换都能现场推导出来,这才是真正吃透这个知识点。

3. 进制转换的三套核心流程:原理、步骤、例子一次说清

3.1 任意进制转十进制:按权展开求和

这个方向的转换最简单,所有进制统一走"按权展开求和"。整数部分最低位的位权是 base⁰,往左每进一位就多乘一次 base;小数部分从 base⁻¹ 开始,往右依次除以 base。以二进制 1101.01 为例:整数部分 1×2³ + 1×2² + 0×2¹ + 1×2⁰ = 8+4+1 = 13;小数部分 0×2⁻¹ + 1×2⁻² = 0.25;合并得 13.25。注意小数点右边第一位的位权是 1/2 而不是 1/10,这是新人最常搞反的地方,一搞反小数部分就全错了。

八进制和十六进制同理:55₈ = 5×8+5 = 45;2D₁₆ = 2×16+13 = 45。你看,二进制 101101、八进制 55、十六进制 2D 转出来都是十进制 45,这正好说明进制只是同一数值的不同写法。工作中我经常用这个公式做反向校验,尤其是解析十六进制报文的时候,先把几个关键位按权展开,心里就有数了,比直接盯着那一串字母猜可靠得多。

3.2 十进制转任意进制:整数除基取余,小数乘基取整

这是四个方向里流程最长的,也是最容易出错的。整数部分用"除基取余":反复用十进制数除以目标进制基数,记下每次的余数,一直除到商为 0,然后把余数从下往上倒序排列。以 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。验证一下:32+8+4+1=45,完美。45 转八进制:45÷8=5 余 5,5÷8=0 余 5,结果是 55;45 转十六进制:45÷16=2 余 13(即 D),2÷16=0 余 2,结果是 2D。

小数部分用"乘基取整":反复用小数部分乘以目标进制基数,取乘积的整数位作为结果的一位,剩下的小数继续乘,直到小数部分变成 0 或达到所需精度。把十进制 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.101。原理上,每次乘 2 是在测试当前小数里包含多少 1/2、1/4、1/8,刚好对应的就是二进制小数位,而不是某个神秘的操作。

提示:整数部分倒序读余数,小数部分顺序读结果,两者方向相反,千万不要混在一起。我见过很多人整数算对了,小数却按倒序写,结果前功尽弃。

3.3 二进制与八进制、十六进制互转:分组法一步到位

这组转换在生产环境里用频率最高,因为根本不用经过十进制,直接分组映射,速度快且零误差。二进制转八进制的规则:以小数点为原点,向左向右每三位一组,整数部分不足三位在左边补 0,小数部分不足三位在右边补 0,然后每组替换成对应的八进制数字。拿 101101.01 来说,整数部分从右往左分是 101 101,对应 5 5;小数部分 01 只有两位,右边补 0 成 010,对应 2,所以结果是 55.2₈。再验证:101101.01 转十进制是 45.25,55.2₈ 转十进制是 5×8+5+2×0.125 = 45.25,一致。

二进制转十六进制只是把三位一组换成四位一组:还是 101101.01,整数部分分组为 0010 1101(左侧补 0),对应 2 和 D;小数部分 0100(右侧补 0),对应 4,结果是 2D.4₁₆。反过来更省事:八进制的每一位展开成三位二进制,十六进制的每一位展开成四位二进制,按顺序拼起来即可。例如 55₈ 每位展开为 101 101,拼起来就是 101101;2D₁₆ 展开为 0010 1101,去掉前导 0 也是 101101。

注意:分组补 0 的方向——整数部分在左侧补 0,小数部分在右侧补 0,补反了结果必错。这一点官方文档里很少单独强调,但实操中问题率极高。

3.4 八进制与十六进制互转:走中转路线最省力

八进制和十六进制之间没有直接的整数次幂关系,所以不能像上面那样一对一映射,常见思路是"八进制→二进制→十六进制"或者"八进制→十进制→十六进制"。我强烈推荐第一种,因为二进制作为中转层不引入任何误差,步骤机械到可以闭着眼做。以 55₈ 转十六进制为例:先展开成二进制 101 101 = 101101,再四位一组补 0 得 0010 1101,映射为 2D₁₆。反向操作同样成立:2D₁₆ 先展开成 0010 1101,去掉前导 0 得 101101,三位一组得 101 101,映射回 55₈。整个过程像流水线一样,练熟了十几秒就能完成,而且每一步都能回头检查。

4. 实战场景与速算技巧:进制在代码里到底怎么用

4.1 四个最常见的实际应用场景

第一个是网页颜色值。网页开发里调色用的是 #RRGGBB 格式,其实是三个十六进制字节,比如 #FF5733 表示红色通道 FF、绿色通道 57、蓝色通道 33,每个通道范围 00~FF,对应十进制 0~255。你调颜色时看到的滚动条,本质上就是在调三个字节的十六进制数值,理解了这一点,很多配色直觉就来自对十六进制的熟悉度。

第二个是类 Unix 文件权限。chmod 755 和 chmod 644 是每个服务器工程师的肌肉记忆,那三位数就是八进制。每一位代表一类用户(文件所有者、所属组、其他人)的权限,每一类权限用三个 bit 组合:读 4、写 2、执行 1。7 表示 rwx 全开,5 表示 r-x(4+1),4 表示只读。九个权限位压成三位八进制数,写起来短,展开成二进制又一眼明白,这就是八进制在权限领域不可替代的原因。

第三个是内存地址和调试信息。调试器打印地址默认用十六进制,因为地址经常涉及对齐、偏移、页大小这些跟二进制强相关的东西,十六进制和二进制可以无脑互转,读完就能心算偏移。我自己调网络报文时,也会先把十六进制数据在脑子里拆成二进制看标志位,比对着字母猜快得多。

第四个是位标志与位运算。很多协议和配置用一个整数管多个开关,一个字节的每一位代表一个选项。这种场景必须建立"位"的直觉:0x01、0x02、0x04、0x08、0x10 分别是第 1 到第 5 位打开,看到 0x0F 就知道低四位全开。这五个值全是 2 的幂,用十六进制写出来一眼秒懂,这也是为什么底层代码里十六进制和位运算总是成对出现。

4.2 常用对照表与心算技巧

0 到 15 的对照表是进制的地基,建议熟练到闭眼能写:

十进制二进制八进制十六进制
0000
1111
21022
31133
410044
510155
611066
711177
81000108
91001119
10101012A
11101113B
12110014C
13110115D
14111016E
15111117F

这个表看起来一堆数字,其实只需要记二进制那一列,八进制是对应三位一组,十六进制是对应四位一组。比如十进制 13 二进制是 1101,十六进制直接就是 D,八进制要补成 001 101 得 15。心算二进制转十进制的根基是 2 的幂:2⁰=1、2¹=2、2²=4、2³=8、2⁴=16、2⁵=32、2⁶=64、2⁷=128、2⁸=256、2⁹=512、2¹⁰=1024。看到 10000000 就条件反射是 128,看到 11000000 就拆成 128+64=192,熟练之后速度非常可观。

4.3 用工具验证结果的低开销方法

手算再熟练也有累的时候,工具验证是零成本保险。系统自带的计算器普遍有程序员模式,可以直接在十六进制、十进制、八进制、二进制之间切换显示,适合随手验算。命令行终端里也可以用 bc 这类计算工具,或者直接用脚本语言,比如这几行代码我几乎每天都会用到:

bin(45) # 输出 0b101101 oct(45) # 输出 0o55 hex(45) # 输出 0x2d int("101101", 2) # 输出 45,第二个参数指定进制

尤其 int() 这种带进制参数的写法,在解析各种协议字段和配置文件时是真正的生产力工具。手算完拿工具验证一下,确认结果无误再继续下一步,能避免很多低级错误。这里也说句实在话:工具是用来兜底的,不是用来替代理解的,你要是连按权展开都不会,工具给的答案对你来说也只是个没意义的数字。

5. 新手最容易踩的坑与排查方法

5.1 余数顺序读反:最经典的低级错误

除基取余法本身不难,但余数的读取顺序一错,整个结果就废了。以 47 转二进制为例,正确的余数序列按除法顺序是 1、1、1、1、0、1,要倒序读才是 101111,等于 47;要是顺着把第一次除法的余数当成最高位,得到 111101,按权展开等于 61,完全对不上。为什么必须倒序?因为最先除出来的余数是最低位,最后一次除法剩下的那个 1 才是最高位。我自己的记忆方法很简单:看到最后一步商变成 0 的那一次除法,它产生的余数就是最高位,从那里写起。每次转完,顺手把最高位对应的 2 的幂验算一下,能揪出一大半错误。

5.2 分组方向搞错:三位和四位的边界线

二进制与八进制、十六进制互转时,分组方向必须从离小数点最近的那位开始,向左向右分开走,而不是从整个数字的左边起头。以二进制 1101 转八进制为例,正确做法是整数部分从右往左三位一组:1 101,左侧补 0 成 001 101,对应 1 和 5,结果是 15₈。要是从左往右分,得到 110 1,右侧补 0 成 110 100,对应 6 和 4,结果是 64₈,差得离谱。十六进制同理:101101 转十六进制,从右往左分组是 10 1101,补 0 成 0010 1101,得 2D;从左往右分组会变成 1011 0100,得 B4。位数不对齐的时候,方向就是生死线。

5.3 小数转换的无限循环:浮点误差的总根源

十进制小数不是都能精确转换成二进制的。0.625 能干净地转成 0.101,但 0.1 不行——0.1 反复乘 2 之后会进入 0.2、0.4、0.8、0.6 的循环,二进制表示是 0.0001100110011……永远写不完。这正是计算机里浮点数精度问题的老根源:你代码里写的 0.1,存储时已经带上了近似误差,所以 0.1+0.2 不等于 0.3 这类现象才会频繁出现。遇到这种情况,正确做法是按业务需要的精度截断,同时心里明确它存在误差,不要拿浮点数做精确判等。我的经验是:能用整数表示金额和计数的场景就尽量用整数,能避免浮点就避免浮点,省去后面一堆精度纠纷。

5.4 十六进制字母记混与常见误读

十六进制 A~F 代表 10 到 15,初学时期特别容易把 A 当成 1、把 F 当成 5,因为字母形状和某些数字确有相似。我给自己的速记是 A=10、B=11、C=12、D=13、E=14、F=15,按顺序锁定。还有一个更隐蔽的坑是前缀误读:看到 0x10 会下意识当十进制 10 读,其实是十六进制 16。碰到带 0x 的数字,先强制自己在心里转成十进制,再谈大小比较。实际工程里十六进制的大小写不敏感,0x2F 和 0x2f 都合法,但你在日志里看到 f 的时候要能认得出它是 15,而不是当成 5。

5.5 常见问题速查表

症状原因处理思路
47 转二进制算成 111101余数顺序读反倒序读余数,最后一次除法的余数是最高位
1101 转八进制得到 64分组方向错误从小数点向左分组,左侧不足补 0
0.1 转二进制写不完小数乘基取整无限循环按精度截断,避免浮点精确判等
把 0x10 当十进制 10前缀含义混淆看到 0x 先转十进制再比较
分组后数值对不上前导 0、尾随 0 补错位置整数在左侧补 0,小数在右侧补 0

我自己刚开始学进制的时候,特别想找那种"一招全搞定"的万能捷径,结果把口诀背了一大堆,遇到带小数的混合数还是卡壳。后来我换了个策略:只留一个"按权展开求和"作为总纲,其他步骤全部从它现场推,再加上几张常见的幂表和对照表辅助心算,速度和准确率反而上来一大截。所以如果你是初学者,别急着背口诀,先把"每一位数字乘上自己的位权再相加"这句话揉碎了吃透,再去做转换练习,练完你会发现自己根本不需要口诀。最后分享一个小习惯:每次写代码遇到进制相关的输入输出,我都随手用工具验算一次,成本几乎为零,但能拦住绝大多数低级错误。等你把这些对应关系内化成条件反射,再看内存地址、权限位、颜色值、协议标志位,就会有一种豁然开朗的感觉——它们从来就不是四套孤立的知识,而是同一件事的四种说法。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询