使用方法
- 在「十进制整数」填要转换的数(示例 255,打开即有)。可以带负号,位数字数不限——填 100 位也不会丢精度,因为解析走
BigInt()而不是Number()。 - 在「目标位宽」选输出宽度。默认「自动(不补零)」只输出有意义的高位;选 1/2/4/8 字节后,正数会按该宽度补零,负数会按该位宽输出二进制补码(例:-255 选 4 字节得
0xFFFFFF01)。 - 「字母大小写」「0x 前缀」「补零对齐位宽」「按字节分组」四个开关随意组合。默认是大写 + 带 0x + 不补零 + 不分组,得到
0xFF——这是寄存器手册与内存 dump 的常见写法。 - 点「转换为十六进制」,或在输入框里直接裸按 Enter(只有一个单行输入框,Enter 没有别的语义)。改动任一控件都会立刻重算。
- 结果区给六张卡片:十六进制结果、原十进制(带千分位)、十六进制位数、折合字节、二进制位数、Number 路径是否一致。下面 24 行精度对照表把两条实现路径的差异逐行列出,可「加载更多」「导出 CSV」「复制对照表」。
这个十进制转十六进制转换器能解决什么问题
一是「大整数被悄悄改掉一个」的问题。只要数值超过 9007199254740991,JavaScript 的 Number 就只能表示 2^53 以上的偶数,奇数会被吸到邻近的偶数上。实测:9007199254740993 走 Number.prototype.toString(16) 得到 20000000000000,走 BigInt 得到 20000000000001,差了 1;而 18446744073709551615(2^64−1)在 Number 路径下变成 0x10000000000000000,凭空多出一位。这类错误不会报错、不会提示,只会让你拿到一个看起来合理但不对的十六进制串。
二是「负数到底该怎么写」的问题。同一个 -255,在两种约定下是两种答案:符号量值写法是 -FF,32 位二进制补码写法是 0xFFFFFF01。嵌入式寄存器、协议帧、校验和计算普遍用补码;而某些配置文件和日志用符号量值。这个转换器把位宽做成显式选择,选 4 字节就出补码、选自动就出符号量值,避免你把补码当成一个巨大的正数读。
三是「格式要对齐」的问题。写寄存器时 0x00FF 与 0xFF 数值相同,但很多电路/协议解析器按固定宽度读取,少一位就错位。勾「补零对齐位宽」后,1 字节输出恒为 2 个字符、4 字节恒为 8 个字符;再勾「按字节分组」,DEADBEEF 读成 DE AD BE EF,和网络字节序、大端小端的讨论对得上。
四是「批量核对」的问题。对照表一次列出 24 个典型值(0 到 2^64−1),并排给出 Number 与 BigInt 两条路径的结果和「一致/不一致」判定。
十进制转十六进制转换器不做这些事:不做十六进制转十进制(那是反方向,见十六进制转十进制转换器);不把一段文字按 ASCII 逐字节转成十六进制(那是文本转十六进制转换器,输入是字符串而不是数);不做浮点数的十六进制表示(IEEE 754 的 0x3F800000 那套需要另一种拆解,本页只处理整数)。
原理与规则说明(含关键变量)
本页调用的具体函数只有四个,且全部是原生:
BigInt(串)——把十进制字符串解析成任意精度整数,不经双精度浮点,因此没有 2^53 上限。BigInt.prototype.toString(16)——按 16 基数输出,字母默认小写,这是 ECMAScript 对toString(radix)的规定(radix 取 2~36)。BigInt.asUintN(位宽, x)——把负数按指定位宽截成无符号位型,这正是「二进制补码」在规范里的定义式,等价于x mod 2^n。String.prototype.padStart(位数, '0')与toUpperCase()——补零与大小写,纯字符串操作,不改数值。
关键参数为什么这样取。① 位宽默认「自动」而不是默认 32 位:默认 4 字节会把 255 变成 0x000000FF,多出 6 个零字符,而多数人只是想要一个等价表示,补零是「对齐」需求而非「转换」需求,所以做成显式勾选。② 负数默认走符号量值而非补码:因为不指定位宽时「补码」没有定义(不知道用几位),只有选了位宽才有唯一答案,所以默认自动 = 符号量值 + BigInt.asUintN 只在选定宽度时介入。③ 字符串长度上限设 400 位:BigInt 本身对位数没有上限,但把 10 万位十进制串转成十六进制会让主线程卡住,400 位已经覆盖 RSA 级别的大整数,超出直接给出提示而不是静默截断。
遵循的标准。整数解析与输出的语义由 ECMAScript 2020(ECMA-262 第 11 版)定义,BigInt 是该版新增的第七种原始类型;十六进制数字的字母大小写都由 RFC 4648 第 8 节规定为「大小写等价、解码器两者都要接受」,本页因此把大小写做成纯显示开关——BigInt('0xff') 与 BigInt('0xFF') 都等于 255,改大小写不改变任何数值。二进制补码是 ISO/IEC 9899(C 语言标准)与各主流指令集对负数位型的约定,BigInt.asUintN 与之一致。数值本身的精度边界来自 IEEE 754 双精度:尾数 52 位显式 + 1 位隐含,故安全整数上限是 2^53−1。
输入经过怎样的转换得到输出。四步:① 字符串 trim() 后按 /^[+-]?\d+$/ 校验,只放行可选正负号加纯数字;② BigInt() 得到精确整数 v;③ 若选了位宽且 v < 0,用 BigInt.asUintN(w, v) 换成无符号位型,否则取 (v < 0 ? -v : v).toString(16);④ 依次套用补零、大小写、0x 前缀、字节分组。全程不出现一次浮点乘法,所以不存在「先算错再取整」的可能。十进制转十六进制转换器的每次输出都严格走完这四步,中间量(精确整数、位型、位数)在结果区是可见的。
三个变量的边界必须记牢。安全整数上限 9007199254740991(2^53−1),超过之后 Number 路径对奇数一定出错;32 位无符号上限 4294967295(0xFFFFFFFF),它的补码与 -1 同型;64 位无符号上限 18446744073709551615(2^64−1),在 Number 路径下会变成 0x10000000000000000。对照表第 17~24 行就是这三条边界的具体现场。
完整示例(数值仅作演示)
示例条件:十进制 255、位宽 自动、大写、带 0x 前缀、不补零、不分组。逐步复算:
255 ÷ 16 = 15余 15 → 最低位十六进制 F;15 ÷ 16 = 0余 15 → 次低位 F;商为 0 停止;- 倒序读出
FF,加前缀得 0xFF; - 反算校验:
0xFF = 15 × 16 + 15 = 240 + 15 = 255✓; - 位数 2(1 字节 = 2 个十六进制字符),二进制位数 8,二进制
11111111; - 若位宽改 2 字节并勾补零:
0x00FF;再勾分组:00 FF; - 对照值:
3735928559 → 0xDEADBEEF(两条路径一致);9007199254740993 → BigInt 0x20000000000001、Number 0x20000000000000(差 1);18446744073709551615 → BigInt 0xFFFFFFFFFFFFFFFF、Number 0x10000000000000000。
对照表前 12 行与这组示例咬合:第 6 行就是 255 → FF,第 12 行 16777215 → FFFFFF 是 3 字节全 1,第 18 行 9007199254740993 的「一致」列为「否」——同一个数在两种写法下结果不同,这就是本页把两条路径并排的原因。
输入范围与对照表
- 十进制整数:可选正负号 + 纯数字,长度 1~400 位。拒绝小数(
255.9)、科学计数(1e3)、千分位(1,024)、十六进制输入(0xFF)、空格与其他字符,每种都有单独的中文提示指出是哪个字段、允许什么。 - 目标位宽:自动 / 8 / 16 / 32 / 64 位。选定位宽后,正数上限分别是
255、65535、4294967295、18446744073709551615;负数下限分别是−128、−32768、−2147483648、−9223372036854775808,越界会明确报错而不是截断。 - 输出格式:大小写、0x 前缀、补零、字节分组四个开关,共 16 种组合,任意组合都不会改变数值,只改变书写。
下面这张 24 行表是精度对照,是本页最有价值的一张表:
| 十进制 | Number 路径 | BigInt 路径 | 一致 | 典型场景 |
|---|---|---|---|---|
| 0 | 0 | 0 | 是 | 零值,最短输出 |
| 15 | F | F | 是 | 单个十六进制位最大值 |
| 255 | FF | FF | 是 | 1 字节上限,本页默认值 |
| 65535 | FFFF | FFFF | 是 | 16 位无符号上限 |
| 1048576 | 100000 | 100000 | 是 | 2^20,内存对齐常客 |
| 16777215 | FFFFFF | FFFFFF | 是 | 24 位全 1,纯白 #FFFFFF |
| 2147483647 | 7FFFFFFF | 7FFFFFFF | 是 | 32 位有符号上限 |
| 4294967295 | FFFFFFFF | FFFFFFFF | 是 | 32 位无符号上限,等于 -1 补码 |
| 3735928559 | DEADBEEF | DEADBEEF | 是 | 调试魔数 |
| 9007199254740991 | 1FFFFFFFFFFFFF | 1FFFFFFFFFFFFF | 是 | 安全整数上限,2^53−1 |
| 9007199254740993 | 20000000000000 | 20000000000001 | 否 | 2^53+1,Number 丢 1 |
| 18446744073709551615 | 10000000000000000 | FFFFFFFFFFFFFFFF | 否 | 2^64−1,uint64 上限 |
表里「一致」列为「否」的三行就是全部风险点:它们都是超过 2^53 的奇数,或者高位全 1 导致四舍五入到下一个 2 的幂。偶数在 2^53 以上仍然精确,这也是为什么 9007199254740992 和 9007199254740994 显示为「是」。
边界与精度说明
- 2^53 是分水岭,且只影响奇数。
Number的尾数有 52 个显式位,能精确表示所有 ≤2^53 的整数;超过之后,相邻可表示值之间的间隔变成 2,于是奇数被舍入到相邻偶数。9007199254740993因此变成9007199254740992。本页走BigInt,从根上避开这条。 - 负数两种写法都要能认。不选位宽时输出
-FF(符号量值),选了 4 字节输出FFFFFF01(补码)。补码下0xFFFFFF01作为无符号数读是4294967041,看起来是个巨大的正数——这不是 bug,是补码的定义:-255 + 2^32 = 4294967041。位宽不够时补码会真的截断:-255选 1 字节,asUintN(8, -255)等于1(因为 −255 + 256 = 1),页面会照实数输出并提示位宽不足,不静默截断。 - 前导零只在显式勾选后出现。自动位宽下
255 → FF而不是00FF;只有选了 2 字节并勾「补零对齐位宽」才补成 4 个字符。这条设计让你的默认输出与计算器、C 语言%x的直觉一致。 - 0x 前缀不参与数值。
0xFF与FF数值相同。本页加了前缀只是为了让输出能直接粘回代码;若你往输入框里贴0xFF,页面会明确提示「检测到十六进制前缀,本页输入的是十进制,请去掉 0x」而不是猜。 - 400 位是性能护栏,不是精度上限。真正把十进制转十六进制是 O(n²) 的除法链,1000 位以上会明显卡顿。400 位已覆盖 1024 位 RSA 的十进制位数的一半以上;超过会给出提示,让你决定是否分段。十进制转十六进制转换器在任何位数下都走同一条 BigInt 路径,区别只是耗时。
- 本页没有浮点分支。所有运算都是整数域,因此不存在
0.1 + 0.2那类问题;你输入的小数会被直接拒绝,而不是先解析成浮点再截断。
常见问题
为什么 9007199254740993 转出来是 20000000000000,不是 …001?
因为你看到的那个结果来自 Number 路径。这个数等于 2^53+1,而 2^53 以上双精度只能表示偶数,奇数会被舍入到相邻偶数,所以 9007199254740993 在内存里就是 9007199254740992,转成十六进制是 20000000000000。本页主结果走 BigInt,得到 20000000000001;对照表单独列出 Number 路径,就是为了让你看到这个差 1 的过程。
-255 为什么有时是 -FF,有时是 FFFFFF01?
两种都是对的,代表两种约定。不指定位宽时没有「用几位」的概念,只能写成符号量值 -FF。一旦选了 4 字节,负数就有了确定的位型,按二进制补码输出 FFFFFF01。嵌入式寄存器、TCP/IP 协议字段、校验和通常按补码存;配置文件与日志常常是符号量值。你按下游解析器的要求选位宽即可。
输出需要大写还是小写?
两者数值完全一样,BigInt('0xff') 与 BigInt('0xFF') 都等于 255(RFC 4648 要求解码器接受两种大小写)。惯例上:C 代码与内存 dump 用大写 0xDEADBEEF,CSS 颜色、URL、哈希串用小写 deadbeef。本页默认大写,一个下拉就能切。
能不能输入 0xFF 反向转换?
不能,本页输入的是十进制,0xFF 会被识别为「带了十六进制前缀」并给出明确提示,而不是猜你的意图。十六进制方向请用十六进制转十进制转换器;如果你输入的是毫无前缀的 FF,页面也只会提示这是非法十进制字符。
八进制、二进制呢?
十进制转二进制用十进制转二进制转换器,转八进制用十进制转八进制转换器。要一次看多个基数,用数字进制转换器。本页只做 10 → 16 这一个方向,把补码、位宽、精度这几件事讲透。
位宽选了 64 位,为什么 2^64−1 反而报错?
因为 2^64−1 是 64 位无符号上限,而本页的位宽语义是「无符号位宽」,它恰好落在边界内,应该能过;真正报错的是 2^64 及以上。如果你填的是 18446744073709551616(2^64),就会提示「超出 8 字节无符号范围 0~18446744073709551615」。负数则下限到 −9223372036854775808(−2^63)。
「按字节分组」会改变数值吗?
不会。它只是每 2 个十六进制字符插一个空格,DEADBEEF 变成 DE AD BE EF,用于对照网络字节序、内存布局阅读。复制结果时带上的空格需要下游按空格或 0x 分段解析;如果你要粘进代码,取消勾选即可。
输入会上传到服务器吗?
不会。整个转换只调用 BigInt 与字符串方法,没有 fetch、XMLHttpRequest、表单提交或 localStorage 写入。你可以打开开发者工具的 Network 面板自证:从输入到出结果零请求。页面刷新后输入框回到默认 255,你填的数不会留下。
相关工具
- 十六进制转十进制转换器:本页的反方向(16 → 10),带 0x 前缀识别与大小写兼容。
- 十进制转二进制转换器:同一套整数逻辑换成 2 基数,位宽与补码规则完全一致。
- 十进制转八进制转换器:10 → 8,用来看文件权限码(如 644 → 0o1204)前后的对照。
- 数字进制转换器:一次列出 2/8/10/16 四个基数,适合通读一个数的多种表示。
- 文本转十六进制转换器:输入是字符串不是数,按编码逐字节转 hex,方向与本页不同但常一起使用。
- 十六进制计算器:在十六进制上做加减乘除与位运算,本页只做基数转换、不做算术。
- 编码解码:查看全部编码解码工具。