使用方法
- 在「待转换数字」填数值(示例 255.625)。36 进制里 10 用 A 表示、35 用 Z 表示,大小写均可。
- 「源进制」填 2~36 的整数(示例 10),「目标进制」同样填 2~36(示例 2)。
- 点「转换」;在任一输入框按回车键也会立即触发。负数会保留负号输出。
- 点「交换进制」把源与目标对调,输入不变再转回去,可自查往返一致性。
- 对照表下方可导出 18 行常用整数的二、八、十六进制对照 CSV(带 BOM,Excel 打开不乱码)。
数字进制转换器能解决什么
站内已有十进制转二进制、十六进制转十进制这类单一方向页,本页补的是它们覆盖不了的口径:一是任意进制——三十六进制里把大整数压成 BYW97UM9S91DLZ68TSI 这种短串(123456789012345678901234567890 的 36 进制形态,19 位),做短码、邀请码时常用;二是超精度整数——超过 Number.MAX_SAFE_INTEGER(9007199254740991,即 2^53−1)的十进制长整数转二进制,本页用 BigInt 霍纳法逐位推进,不丢精度;三是带小数的转换——255.625 这类数字,整数部分与小数部分分别处理。反方向的专用需求(例如只要十进制转十六进制)请用站内十进制转十六进制转换器,本页不与它抢词。
原理与变量:parseInt、toString 与霍纳法
常规路径调用的是 parseInt(s, radix) 与 Number.prototype.toString(radix),两者都规定 radix 上限 36——因为拉丁字母只有 26 个,0-9 加 A-Z 正好 36 个数码,这是上限取 36 的唯一原因。但直接交给这两个函数有两个坑:其一,前缀歧义——parseInt("0x1f") 不带第二参数也返回 31(自动按十六进制),parseInt("0b101") 却返回 0(把 0b 当十进制解析到 b 处截断),而 Number("1e3") 是 1000、parseInt("1e3") 却停在 e 得 1;数字进制转换器因此先按字符表逐位校验再计算,杜绝这些静默歧义。其二,精度上限——parseInt 返回 Number,超过 2^53−1 的整数在尾数 53 位里放不下;而 BigInt() 构造器又不接受第二个 radix 参数(只认 0x/0o/0b 前缀),所以本页对整数部分自实现霍纳法:从左到右 v = v × radix + 当前位数字,全程 BigInt,任意长度整数都不丢位。小数部分走另一条路:按位累加 d × radix^−i 得到 Number 值,再反复乘 radix 取整数部分输出数码,最多输出 16 位并去尾零。
完整示例(数值仅作演示)
默认输入 255.625、源 10 进制、目标 2 进制:整数部分 255 按霍纳法得 11111111(8 位,恰是一个字节能表示的最大值);小数部分 0.625 反复乘 2 得 .101(0.625×2=1.25 取 1,0.25×2=0.5 取 0,0.5×2=1.0 取 1 即止),拼成 11111111.101。再验证一组循环小数:0.1 转二进制是 0.000110011001100…,0011 无限循环,这正是「0.1 + 0.2 = 0.30000000000000004」的根源;而 0.625 能被 2 的幂精确表示,所以有限三位就结束了。按「交换进制」把 11111111.101 转回 10 进制,得 255.625,往返一致。
输入范围与对照表
进制允许 2~36、输入允许负号、一个小数点与对应进制的合法数码,其余字符会被按位置点名报错。下表列常用整数的二、八、十六进制形态(最后三行超出 2^53 或为 32 位边界值,供精度对照),默认显示 12 行,点「加载更多」补出后 6 行。
| 十进制 | 二进制 | 八进制 | 十六进制 |
|---|---|---|---|
| 5 | 101 | 5 | 5 |
| 10 | 1010 | 12 | A |
| 16 | 10000 | 20 | 10 |
| 100 | 1100100 | 144 | 64 |
| 255 | 11111111 | 377 | FF |
| 1024 | 10000000000 | 2000 | 400 |
| 4095 | 111111111111 | 7777 | FFF |
| 65535 | 1111111111111111 | 177777 | FFFF |
| 1000000 | 11110100001001000000 | 3641100 | F4240 |
| 2147483647 | 1111111111111111111111111111111 | 17777777777 | 7FFFFFFF |
| 9007199254740991 | 53 个 1 | 377777777777777777 | 1FFFFFFFFFFFFF |
| 123456789012345678901234567890 | 97 位二进制(本页可实转) | — | 18EE90FF6C373E0EE4E3F0AD2 |
输入范围、边界与精度说明
转换链路:读入字符串 → 校验进制为 2~36 整数 → 校验数码(逐字符查「0-9A-Z」表,数码值必须小于源进制)→ 整数部分 BigInt 霍纳 → 小数部分 Number 乘基取整 → 目标进制输出。边界上:进制为空、含小数、小于 2、大于 36;输入为空;出现第二个小数点;出现当前进制不认识的数码(如三进制里出现「8」);小数段超过 40 位——数字进制转换器对以上每一种都给出指明字段与原因的提示,不会静默截断。精度边界有三条硬线:整数超过 2^53−1 时 Number 路径必丢精度,本页自动走 BigInt;小数输出封顶 16 位,因为双精度只有约 15~17 位有效数字,再多位是虚假精度;0.1 这类在目标进制无限循环的分数只能取近似,不是本页的缺陷而是进制数学本身的性质。负数按「符号 + 绝对值」转换输出,不做补码展开——想知道 −5 在 8 位补码下的形态,结果是 11111011,这一口径在浮点与整数定宽语境里才成立,本页是数值口径。
常见问题
为什么进制最大只到 36?
ECMAScript 规定 parseInt 与 toString(radix) 的 radix 范围是 2~36:数码用完 0-9 之后只剩 26 个拉丁字母,36 就是能无歧义书写的上限,超出会直接抛 RangeError。
parseInt("0b101") 为什么等于 0?
parseInt 只在无第二参数时自动识别 0x 前缀,不认 0b/0o:它把 0b101 按十进制解析,读到 b 处停止,于是只剩前导的 0。要转二进制请显式传 radix=2 或用本页。
0.1 转二进制为什么是无限循环?
0.1 = 1/10,而 10 含因子 5,不在 2 的幂里,所以二进制下必然无限循环(0011 循环)。双精度只能存 53 位有效尾数,末尾四舍五入成 1101 结尾,这就是浮点误差的来源。
超过 2^53 的整数为什么其他工具会出错?
Number 的尾数只有 53 位,超过 9007199254740991 的整数相邻可表示值间隔已大于 1,parseInt 得到的值先丢精度再转换;本页整数部分用 BigInt 霍纳法逐位推进,不受这条上限约束。
负数怎么转?补码呢?
本页输出「负号 + 绝对值的进制表示」,如 −5 转 2 进制得 −101。补码是定宽整数的存储口径(8 位下 −5 是 11111011),依赖位宽设定,与本页的数值口径不同,故不混算。
三十六进制里 255 为什么是 73?
7 × 36 + 3 = 255。36 进制把两位数码用满:FF(十六进制的 255)到 36 进制只需「73」,基数越大串越短,这是短码场景选 36 的原因。
转换结果可以用来做 Base64 吗?
不可以。Base64 是按 6 位一组重排字节的编码,处理的是字节序列;本页处理的是数的书写进制,两者仅在「都出现字母」这一点上相似,语义无关。
输入会被上传吗?
不会。全部计算在浏览器本地由内联脚本完成,无任何网络请求,可在开发者工具 Network 面板自查。