IEEE 754 浮点数转换器
在线 IEEE 754 浮点数转换器,支持半精度、单精度、双精度与 bfloat16,浮点数与十六进制/二进制互转。查看精确存储值、舍入误差与位布局,全部在浏览器本地完成,数据不上传。
| 符号 | |
| 指数 | |
| 尾数 |
- 你输入的值
- 实际存储的值
- 舍入误差
- 前一个
- 后一个
- ULP(间距)
| 格式 | 总位数 | 符号 | 指数 | 尾数 | 偏置 | 最大有限值 | 十进制位数 |
|---|---|---|---|---|---|---|---|
| binary16 (FP16) | 16 | 1 | 5 | 10 | 15 | 65504 | ~3.3 |
| bfloat16 | 16 | 1 | 8 | 7 | 127 | ≈3.39×10³⁸ | ~2.3 |
| binary32 (FP32) | 32 | 1 | 8 | 23 | 127 | ≈3.40×10³⁸ | ~7.2 |
| binary64 (FP64) | 64 | 1 | 11 | 52 | 1023 | ≈1.80×10³⁰⁸ | ~15.9 |
什么是 IEEE 754 浮点数?
IEEE 754 是定义计算机如何用二进制存储实数的标准。每个值被打包进三个字段:一个符号位、一个指数(以带偏置的形式存储,从而既能表示极大也能表示极小的数量级),以及一个保存有效数字的尾数。几乎所有 CPU、GPU 和编程语言都采用它,这也是为什么同样的舍入怪象会一模一样地出现在 JavaScript、Python、C 和 SQL 中。
关键在于:二进制浮点只能表示形如 m × 2ⁿ 的数。像 0.1 这样的十进制小数在二进制中是无限循环小数——0.000110011001100…——因此格式实际存储的是最接近的可表示邻居。单精度下这个邻居是 0.100000001490116119384765625;双精度下是 0.1000000000000000055511151231257827021181583404541015625。两者都不是 0.1。所有下游的怪现象——0.1 + 0.2 ≠ 0.3、求和漂移、相等判断失败——全都源自这一个事实,而本转换器把它变得可见:直接打印精确存储值,而不是舍入回去的近似值。
该标准还为特殊值保留了位模式。指数全 1 编码 ±Infinity(尾数为零)或 NaN(尾数非零);指数全 0 编码带符号零(尾数为零)或次正规数(尾数非零),后者以降低的精度填补紧邻零的下溢空隙。本工具覆盖的四种格式——binary16/FP16、bfloat16、binary32/FP32、binary64/FP64——区别仅在于各字段分到多少位:指数位越多范围越大,尾数位越多精度越高。机器学习偏爱的 bfloat16 其实就是把 FP32 的低 16 个尾数位截掉:范围相同,精度粗得多。
一个有用的心智模型是:可表示的浮点数在数轴上构成一张网格,其间距——最后一位上的一个单位,即 ULP——在每个 2 的幂处翻倍。在 1.0 附近,double 的网格间距约为 2.22 × 10⁻¹⁶;在 2⁵³ 附近则达到整整 1,这就是为什么 double 无法可靠地数到 2⁵³ 以上。本工具的相邻值面板直接展示这张网格:无论你输入什么值,都能看到它前后两个可表示值以及它们之间的精确间距。
// Float ↔ hex through the raw IEEE 754 bits (works in any browser / Node.js)
const buf = new DataView(new ArrayBuffer(8));
function floatToHex32(value) {
buf.setFloat32(0, value); // rounds to nearest even
return '0x' + buf.getUint32(0).toString(16).toUpperCase().padStart(8, '0');
}
function hexToFloat32(hex) {
buf.setUint32(0, parseInt(hex, 16));
return buf.getFloat32(0);
}
floatToHex32(0.1); // '0x3DCCCCCD'
floatToHex32(3.14159); // '0x40490FD0'
hexToFloat32('3DCCCCCD'); // 0.10000000149011612 核心特性
四种格式,一个视图
半精度(FP16)、bfloat16、单精度(FP32)、双精度(FP64)——一键切换,整页立即重新计算,几秒钟就能对比同一个数在各格式下的落点。
可点击的位网格
每一个位都是按钮。翻转符号位、微调指数、拨动某个尾数位,十进制、十六进制和二进制视图即刻更新——这是建立编码直觉最快的方式。
精确存储值,而非近似值
工具用精确的大整数运算算出所存位模式的完整十进制展开——double 下 0.1 的全部 55 位数字——并给出相对你输入值的精确带符号舍入误差。
相邻值与 ULP
查看当前数字前后两个可表示值,以及它们之间的精确间距(ULP)——正是这个网格间距决定了你在任意数量级上实际拥有多少精度。
特殊值一键直达
快捷按钮可载入所选格式的 ±0、±Infinity、NaN、最小次正规数和最大有限值,分类徽章会标明当前位模式编码的是什么。
可分享的永久链接,零上传
「复制链接」把格式和精确位模式编码进 URL——非常适合 bug 报告、代码评审和教学演示。一切都在你的浏览器中运行;你输入的任何内容都不会离开页面。
IEEE 754 转换示例
单精度下的 0.1 — 经典舍入误差
0.1
0x3DCCCCCD — 实际存储为 0.100000001490116119384765625
十进制 0.1 在二进制中没有有限表示,因此 IEEE 754 存储的是最接近的可表示值。在单精度(FP32)下这个值是 0x3DCCCCCD,即精确的 0.100000001490116119384765625——比 0.1 大约多出 1.49 × 10⁻⁹。本工具逐位展示这个精确存储值和精确误差,而不是编程语言打印回来的、已被舍入的「0.1」。仅这一个例子就能解释大多数浮点数怪象,包括为什么 0.1 + 0.2 不等于 0.3。
浮点数转十六进制:FP32 下的 3.14159
3.14159
0x40490FD0
在选中单精度(FP32)时输入 3.14159,十六进制框显示 0x40490FD0——符号位 0,偏置指数 128(即 2¹),尾数 0x490FD0。实际存储的值是 3.141590118408203125,比你输入的略大一点。十六进制形式正是你在网络抓包、GPU 缓冲区、寄存器视图和序列化二进制文件中看到的形式,而且转换是双向的:把 40490FD0 粘贴到十六进制框即可解码回来。
FP16 上限:65504 是半精度的尽头
65504
0x7BFF — FP16 最大的有限值
半精度只有 5 个指数位和 10 个尾数位,因此其最大有限值是 65504(0x7BFF)。输入 65520 或更大的数,结果就会舍入为 Infinity(0x7C00)——这是把机器学习模型量化到 FP16 时的真实隐患。切换到 bfloat16,同样的 65520 就能轻松容纳,因为 bfloat16 保留了 FP32 的 8 个指数位(范围),代价是放弃尾数位(精度)。这种取舍正是 ML 训练偏爱 bfloat16、而紧凑存储偏爱 FP16 的原因。
−0 与 +0:两种位模式,同一个值
-0
0x80000000(FP32),而 +0 是 0x00000000
IEEE 754 存在带符号的零:−0 只置符号位(FP32 下为 0x80000000),而 +0 是全零。它们在所有语言中比较相等,但 1/−0 得 −Infinity、1/+0 得 +Infinity,所以这个差异是可观察的。在工具中点击符号位即可在两者之间切换,你会看到分类徽章始终停在「零」上而十六进制值发生变化——一次点击就能说明为什么位级相等和数值相等是两回事。
如何转换 IEEE 754 浮点数
- 1
选择浮点格式
默认选中单精度(FP32)。处理 JavaScript/Python 风格的数字请切换到双精度(FP64);机器学习和图形领域常用的 16 位格式则选半精度(FP16)或 bfloat16。
- 2
输入十进制数
输入任意值——0.1、-2.5e3、65504——或使用特殊值快捷按钮载入 ±0、±Infinity、NaN、最小次正规数和最大有限值。转换随输入即时进行。
- 3
阅读彩色标注的位布局
符号位、指数字段和尾数以不同颜色高亮显示,字段分解表列出原始位、偏置运算过程和隐含前导位。
- 4
查看精确存储值与误差
精度面板打印出实际存储的值——每一位数字都经过精确计算——以及它与你输入值之间的舍入误差,还有前后两个相邻可表示值和 ULP 间距。
- 5
翻转位、粘贴十六进制、复制结果
点击任意位即可翻转,或粘贴十六进制(3DCCCCCD)和二进制位串解码回十进制。可复制十六进制、二进制、精确值,或复制一条能复现当前位模式的分享链接。
常见浮点数错误
相信打印值而不是存储值
语言打印浮点数时会舍入到能往返还原的最短字符串,所以 0.1 看起来干净利落,存储值却并非如此。判断精度要看精确展开,而不是 print() 显示了什么。
print(0.1) # 0.1 — 看起来精确,其实不是
0.1 实际存储值(FP64)= 0.1000000000000000055511151231257827021181583404541015625
用精确相等比较浮点数
0.1 + 0.2 落在位模式 0x3FD3333333333334 上,而字面量 0.3 是 0x3FD3333333333333——相差一个 ULP,所以 == 为 false,尽管两者打印出来都像 0.3。
if (0.1 + 0.2 === 0.3) { … } // 永远不会执行 if (Math.abs(a - b) < 1e-9) { … } // 按你的数据量级选定容差 量化到 FP16 前不检查范围
FP16 的最大有限值是 65504。任何更大的数都会变成 Infinity,而 Infinity 一旦进入计算就会传播。向下转换前先检查最大值——或者改用保留 FP32 范围的 bfloat16。
fp16(65520) → Infinity (0x7C00) — 静默溢出
bf16(65520) → 有限值(bfloat16 保留 8 个指数位)
用相等判断测试 NaN
NaN 是唯一不等于自身的值——这是有意的设计,让失败的计算无法伪装成正常数字。请使用语言提供的 isNaN 检查而不是 ==,并记住存在数以百万计的不同 NaN 位模式。
if (x === NaN) { … } // 永远为 false,即使 x 就是 NaN if (Number.isNaN(x)) { … } // 正确的检测方式 IEEE 754 转换器能做什么
- 调试序列化的二进制数据
- 把在网络抓包、GPU 缓冲区、寄存器转储或文件格式中找到的十六进制值粘贴进来,解码出精确的十进制值——也可以反向转换来编写测试夹具。字节序提示:所显示的十六进制是大端(big-endian)位模式;如果你的转储是小端序(little-endian),粘贴前请先反转字节顺序。
- 理解 ML 量化
- 检查你的数值能否扛过 FP16 的 65504 上限,逐位对比 FP16 与 bfloat16 的精度损失,并检视梯度会发生下溢的次正规数区间。
- 解释浮点数 bug
- 当同事问为什么两个「相等」的数不一样时,发一条永久链接,同时展示两个位模式和精确存储值——争论自然平息。更长的数据转储可搭配文本对比工具使用。
- 学习或讲授编码格式
- 当学生可以亲手点击指数位、看着偏置运算实时更新时,计算机体系结构课程就变得具体了。字段分解表的画法与教科书中的格式示意图一致。
- 解码嵌入式与工业寄存器
- Modbus、CAN 和传感器载荷经常以原始十六进制字的形式携带 FP32 值。把该字粘贴到这里即可读出物理量,无需另写临时脚本。
IEEE 754 格式与特殊值
- 四种二进制格式一览
- binary16(FP16):1 符号位 + 5 指数位 + 10 尾数位,偏置 15,最大值 65504,约 3.3 位十进制数字。bfloat16:1 + 8 + 7,偏置 127,最大值 ≈ 3.39 × 10³⁸,约 2.3 位。binary32(FP32):1 + 8 + 23,偏置 127,最大值 ≈ 3.40 × 10³⁸,约 7.2 位。binary64(FP64):1 + 11 + 52,偏置 1023,最大值 ≈ 1.80 × 10³⁰⁸,约 15.9 位。规律很清楚:指数位换范围,尾数位换精度,而 bfloat16 刻意用全部精度优势换取 FP32 的范围。
- 值是如何组装出来的
- 正规数的解码公式是 (−1)^sign × 1.mantissa × 2^(exponent − bias)。前导 1 是隐含的——它不被存储,这就是 23 位尾数字段能提供 24 位精度的原因。存储的指数等于真实指数加偏置(FP32 为 127),因此 2⁰ 存储为 01111111。本工具的字段分解表会针对当前值逐步展示这套运算。
- 特殊值:被保留的指数模式
- 指数全 1 且尾数为零是 ±Infinity;尾数非零则是 NaN(规范的 quiet NaN 会置上尾数的最高位)。指数全 0 且尾数为零是 ±0;尾数非零则是次正规数,按 0.mantissa × 2^(1 − bias) 解码——没有隐含前导 1。这些规则在四种格式中完全一致,所以同一组快捷值在每种格式下都能用。
- 舍入:就近舍入,平局取偶
- 当一个值落在两个可表示数之间时,IEEE 754 的默认模式舍入到较近的那个;恰好在正中间时,取尾数最后一位为 0 的那个(平局取偶),以避免系统性漂移。本转换器把你的十进制输入收窄到目标格式时应用的正是这条规则,误差面板会精确显示由此产生的带符号差值。
- ULP:浮点数的网格间距
- 可表示的浮点数并非均匀分布——相邻值之间的间距(最后一位上的一个单位)在每个 2 的幂处翻倍。在 1.0 附近,double 的 ULP 是 2⁻⁵² ≈ 2.22 × 10⁻¹⁶;到 2⁵³ 附近 ULP 达到 1.0,整数开始被跳过。相邻值面板会精确打印当前的 ULP——这才是「我的数字在这里有多精确?」的诚实答案。
浮点数最佳实践
- 永远不要用 == 比较浮点数
- 任何运算之后,两个数学上相等的表达式都可能相差一个 ULP。请使用与数量级匹配的容差来比较——或者统计两个位模式之间相差多少个 ULP,本工具可以直接查看。
- 别把金额放进二进制浮点数
- 没有任何 2 的幂网格能精确容纳 0.10,用浮点数存货币会累积出肉眼可见的误差。请改用整数(分)或十进制类型;本页的精确存储值面板就是长期有效的证据。
- 按范围而非习惯选择 16 位格式
- 如果你的值可能超过 65504——损失函数、梯度、物理量尖峰——FP16 会溢出为 Infinity,而 bfloat16 安然无恙。如果所有值都被归一化到窄区间,FP16 多出的尾数位能带来明显更好的精度。
- 收窄转换时当心双重舍入陷阱
- 在罕见的中点情形下,十进制 → double → half 的转换结果可能与十进制 → half 直接转换相差一个 ULP。本工具把你的十进制输入一步舍入到目标格式,所以你看到的就是诚实的 IEEE 754 答案。
- 预期整数在 2⁵³ 之上会失真
- double 能精确存储到 2⁵³ 为止的每一个整数,之后开始跳数——2⁵³ + 1 无法表示。若你处理的 ID 或计数器接近该量级,请使用 64 位整数或字符串,并把可疑值放到这里做位级检查。
IEEE 754 转换器常见问题
为什么 0.1 + 0.2 不等于 0.3?
什么是 IEEE 754?
FP16 和 bfloat16 有什么区别?
什么是次正规数(subnormal / denormal)?
该用 float 还是 double?
如何手工把浮点数转成十六进制?
使用这个转换器时我的数据会被上传吗?
相关工具
查看所有工具 →进制转换器 — 二进制、十六进制、十进制、八进制互转
转换工具
在线免费进制转换工具,支持二进制、八进制、十进制、十六进制及 2-36 任意进制互转。无需注册,数据不离开浏览器,即时获取结果。
颜色转换器 — HEX、RGB、HSL 与 OKLCH
转换工具
在浏览器中将 HEX 转 RGB、HSL、OKLCH、OKLAB 与 CMYK,一键复制任意格式。免费、免注册,您的颜色永远不会离开本页。
HEX 转 CMYK 转换器
转换工具
在浏览器中把 HEX 颜色转成 CMYK。基于 sRGB 的朴素近似,适合印前预览。免费、免注册,您的颜色始终保留在本地。
HEX 转 HSL 转换器
转换工具
在浏览器中把任意 HEX 颜色转成 HSL —— 3 位、6 位以及带 alpha 的 8 位全部支持。免费、即时、免注册,您的颜色永远不会离开本页。
HEX 转 OKLCH 转换器
转换工具
把 HEX 转成 OKLCH,直接喂给 Tailwind v4 设计 token。实时输出感知均匀的三元组,带 Display P3 色域提醒。免费,纯浏览器运行。
HEX 转 RGB 转换器
转换工具
在浏览器中把任意 HEX 颜色代码转成 RGB —— 3 位、6 位以及带 alpha 的 8 位 HEX 全部支持。免费、即时、免注册,您的颜色永远不会离开本页。