十进制转十六进制转换器

一个输入框填十进制整数,一个下拉选位宽,输出十六进制串。核心是用 BigInt 而不是 Number:只要超过 9007199254740991,Number.prototype.toString(16) 就会返回偏移 1 或 2 的错误结果,而这个转换器走 BigInt(x).toString(16),多少位都不会差一个数。

只接受十进制数字,可带正负号;不接受小数点、指数、千分位逗号
选定位宽后,负数按该位宽的二进制补码输出
十进制 255 → 十六进制 0xFF
除 16 取余(低位先出,最后倒序)
  255 ÷ 16 = 15 余 15   → 末位 F
   15 ÷ 16 =  0 余 15   → 次位 F
倒序读出:FF,加前缀 0xFF
反算校验:0xFF = 15 × 16 + 15 = 240 + 15 = 255 ✓
位数 2(每 1 字节 = 2 个十六进制字符),二进制位数 8
补零演示:位宽选「2 字节(16 位)」并勾选「补零对齐位宽」→ 0x00FF
按字节分组:0x FF → 00 FF

三个对照值(同一条转换,两种写法结果不同)
  3735928559         → 0xDEADBEEF(BigInt 与 Number 一致,< 2^53)
  9007199254740993   → BigInt 0x20000000000001;Number 0x20000000000000 ★ 差 1
  18446744073709551615 → BigInt 0xFFFFFFFFFFFFFFFF;Number 0x10000000000000000
负数:-255 选 4 字节 → 0xFFFFFF01(补码),不选位宽 → -FF(符号量值)

(以上为服务端直出的演示值,改动任一控件或点「转换为十六进制」即用你的输入覆盖)
全部整数运算走 BigInt,不经浮点,因此不受 2^53 精度上限影响

精度对照表(Number 路径 vs BigInt 路径,24 行)

十进制Number 路径BigInt 路径一致说明
000是零是最短输出,不补零
111是最小正整数
10AA是首次出现字母 A
15FF是单个 nibble 的最大值
161010是进位一次,16 进制 0x10
255FFFF是本页默认示例,1 字节上限
256100100是1 字节溢出到 2 字节
4095FFFFFF是12 位全 1
65535FFFFFFFF是2 字节上限(unsigned short)
655361000010000是2 字节溢出到 3 字节
1048576100000100000是2^20,3 字节
16777215FFFFFFFFFFFF是3 字节上限(RGB 白)
21474836477FFFFFFF7FFFFFFF是32 位有符号上限 INT_MAX
21474836488000000080000000是补码里的最小负数位型
4294967295FFFFFFFFFFFFFFFF是32 位无符号上限,-1 的补码
3735928559DEADBEEFDEADBEEF是经典调试魔数,网络字节序演示
90071992547409911FFFFFFFFFFFFF1FFFFFFFFFFFFF是Number.MAX_SAFE_INTEGER,2^53−1
90071992547409922000000000000020000000000000是2^53,偶数仍可精确表示
90071992547409932000000000000020000000000001否2^53+1,Number 向下取偶数丢 1
90071992547409942000000000000220000000000002是2^53+2,偶数精确
90071992547409952000000000000420000000000003否2^53+3,Number 偏大 1
90071992547409962000000000000420000000000004是2^53+4,偶数精确
922337203685477580780000000000000007FFFFFFFFFFFFFFF否2^63−1,Long 上限,Number 完全走样
1844674407370955161510000000000000000FFFFFFFFFFFFFFFF否2^64−1,uint64 上限,差 1 位

使用方法

  1. 在「十进制整数」填要转换的数(示例 255,打开即有)。可以带负号,位数字数不限——填 100 位也不会丢精度,因为解析走 BigInt() 而不是 Number()。
  2. 在「目标位宽」选输出宽度。默认「自动(不补零)」只输出有意义的高位;选 1/2/4/8 字节后,正数会按该宽度补零,负数会按该位宽输出二进制补码(例:-255 选 4 字节得 0xFFFFFF01)。
  3. 「字母大小写」「0x 前缀」「补零对齐位宽」「按字节分组」四个开关随意组合。默认是大写 + 带 0x + 不补零 + 不分组,得到 0xFF——这是寄存器手册与内存 dump 的常见写法。
  4. 点「转换为十六进制」,或在输入框里直接裸按 Enter(只有一个单行输入框,Enter 没有别的语义)。改动任一控件都会立刻重算。
  5. 结果区给六张卡片:十六进制结果、原十进制(带千分位)、十六进制位数、折合字节、二进制位数、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 那套需要另一种拆解,本页只处理整数)。

原理与规则说明(含关键变量)

本页调用的具体函数只有四个,且全部是原生:

关键参数为什么这样取。① 位宽默认「自动」而不是默认 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 前缀、不补零、不分组。逐步复算:

对照表前 12 行与这组示例咬合:第 6 行就是 255 → FF,第 12 行 16777215 → FFFFFF 是 3 字节全 1,第 18 行 9007199254740993 的「一致」列为「否」——同一个数在两种写法下结果不同,这就是本页把两条路径并排的原因。

输入范围与对照表

下面这张 24 行表是精度对照,是本页最有价值的一张表:

十进制Number 路径BigInt 路径一致典型场景
000是零值,最短输出
15FF是单个十六进制位最大值
255FFFF是1 字节上限,本页默认值
65535FFFFFFFF是16 位无符号上限
1048576100000100000是2^20,内存对齐常客
16777215FFFFFFFFFFFF是24 位全 1,纯白 #FFFFFF
21474836477FFFFFFF7FFFFFFF是32 位有符号上限
4294967295FFFFFFFFFFFFFFFF是32 位无符号上限,等于 -1 补码
3735928559DEADBEEFDEADBEEF是调试魔数
90071992547409911FFFFFFFFFFFFF1FFFFFFFFFFFFF是安全整数上限,2^53−1
90071992547409932000000000000020000000000001否2^53+1,Number 丢 1
1844674407370955161510000000000000000FFFFFFFFFFFFFFFF否2^64−1,uint64 上限

表里「一致」列为「否」的三行就是全部风险点:它们都是超过 2^53 的奇数,或者高位全 1 导致四舍五入到下一个 2 的幂。偶数在 2^53 以上仍然精确,这也是为什么 9007199254740992 和 9007199254740994 显示为「是」。

边界与精度说明

常见问题

为什么 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,你填的数不会留下。

相关工具