使用方法
- 数值默认
0.1,支持小数与负数。改完立即重算,光标停在输入框里按 Enter 同样触发,不必去点按钮。 - 位宽默认 64 位(双精度),可以切成 32 位(单精度)。切换后指数段从 11 位变成 8 位,偏移从 1023 变成 127,十六进制也从 16 位缩到 8 位。
- 结果区第一行给结论:数值、精度与十六进制。下面七行依次是符号位、指数位(含偏移还原)、尾数位、完整位串、1 + 11 + 52 三段分组,以及由位串回读的校验值。
- 符号位为 0 表示非负,1 表示负;指数位给的是偏移后的原值与减掉偏移后的真实指数,两个数都列出来,避免把偏移码当成补码读。
- 尾数位默认只存小数部分。整数部分的那个 1 是隐含的,不占存储位,所以 52 位尾数实际提供 53 位精度。
- 工具区下方是 20 行常见数值位布局表,默认显示 12 行,点「加载更多」展开余下 8 行,点「导出 CSV」存成带字节序标记的文件。
- 「复制结果」带走结果区整段;「复制对照表」复制正文里那张 12 行位布局表,制表符分隔,可直接粘进表格软件。
- 数值写成非数字会给出明确提示;输入 Infinity 与 -Infinity 会被当成合法的特殊值处理,并给出对应的位型。
这个数字转比特转换器能解决什么
浮点数在内存里是什么样,靠十进制打印值是看不出来的:0.1 打印出来是 0.1,可它存进去的并不是 0.1。数字转比特转换器这一页做的就是把十进制数按 IEEE 754 摊成 64 个(或 32 个)比特,让符号、指数、尾数三段各就各位,十六进制与位串都给全。
第一类是解释精度问题。为什么 0.1 + 0.2 不等于 0.3?把 0.1 转成比特就能看到:它的尾数是 1001 无限循环,存到第 52 位就被截断,末尾还进了一位。两个都不精确的数相加,结果自然对不上 0.3。这类问题靠讲道理讲不明白,看一次位串就懂了。
第二类是对协议与文件格式。网络协议、二进制文件、序列化格式里写的常常是 8 字节或 4 字节的浮点。要确认对方写进去的到底是单精度还是双精度、字节序怎么排,先把数值转成十六进制与位串,再和抓到的字节比对,比猜快得多。
第三类是教学与自查。讲 IEEE 754 时,「指数用偏移码」「尾数有隐含前导 1」「零与非规格化数各有专门位型」这三条都能在本页直接验证:输入 0 看全零位型,输入 1.0 看指数段正好是偏差值,输入 0.5 看指数比 1.0 小一位。
计算原理与变量说明
IEEE 754 把一个浮点数拆成三段:符号位 s、指数段 E、尾数段 M,真值为 (-1)s × 1.M × 2E-bias(规格化数)。指数不用补码而用偏移码:把真实指数加上一个偏差再存,好处是指数段全 0 到全 1 的大小顺序与真实指数一致,比较两个数时可以直接按整数比。
| 精度 | 总位 | 符号 | 指数 | 尾数 | 偏移 | 隐含精度 |
|---|---|---|---|---|---|---|
| 单精度 float | 32 | 1 | 8 | 23 | 127 | 24 位 |
| 双精度 double | 64 | 1 | 11 | 52 | 1023 | 53 位 |
指数是偏移码,不是补码。双精度偏差 1023,所以指数段 01111111011(十进制 1019)对应的真实指数是 1019 − 1023 = −4。1.0 的指数段是 01111111111(1023),真实指数 0;0.5 的指数段是 01111111110(1022),真实指数 −1。指数段从小到大正好对应真实指数从小到大,这是偏移码相对补码的好处。
尾数有隐含前导 1。规格化数的二进制一定是 1.xxxx 的形式,那个整数部分的 1 对所有规格化数都一样,于是标准干脆不存它,只存小数点后面的部分。所以 23 位尾数实际给 24 位精度,52 位实际给 53 位。指数段全 0 时例外:那时是非规格化数或零,隐含位按 0 算。
0.1 在二进制里是循环小数。十进制的 0.1 换成二进制是 0.0001100110011……,其中 1001 无限循环,永远写不完。双精度只能留 52 位,第 53 位按舍入规则进位,于是存进去的值比 0.1 略大一点点。这就是 0.1 + 0.2 !== 0.3 的根:两边都不精确。
特殊值各有专门位型。指数段全 1 且尾数全 0 是无穷(符号位决定正负),指数段全 1 且尾数非 0 是 NaN,指数段与尾数全 0 是零(同样有 +0 与 −0 之分)。所以「指数段全 1」不能当作一个很大的数来读。
完整示例(数值仅作演示)
默认一组:输入 0.1、位宽 64 位,十六进制为 3fb999999999999a,位串为 0011111110111001100110011001100110011001100110011001100110011010。按 1 + 11 + 52 分段是 0 | 01111111011 | 1001100110011001100110011001100110011001100110011010,指数段 1019 减 1023 得 −4。
对照一组:切到 32 位单精度,1.0 得 3f800000,位串 00111111100000000000000000000000;-2.5 得 c0200000,位串 11000000001000000000000000000000,符号位为 1;3.14 得 4048f5c3,位串 01000000010010001111010111000011。
双精度一组:1.0 得 3ff0000000000000,指数段 01111111111 正好是偏差 1023;3.14 得 40091eb851eb851f。把 3.14 从 64 位切到 32 位,回读值会从 3.14 变成 3.140000104904175,一眼就能看出单精度丢了多少。
常见数值位布局对照表
下表列出常见数值在两种位宽下的十六进制与分段位串。分段按「符号 | 指数 | 尾数」书写,单精度是 1 + 8 + 23,双精度是 1 + 11 + 52。「复制对照表」按钮复制的就是这张表。
| 数值 | 位宽 | 十六进制 | 分段位串(符号 | 指数 | 尾数) |
|---|---|---|---|
| 0 | 32 | 00000000 | 0 | 00000000 | 00000000000000000000000 |
| 0.5 | 32 | 3f000000 | 0 | 01111110 | 00000000000000000000000 |
| 1 | 32 | 3f800000 | 0 | 01111111 | 00000000000000000000000 |
| 2 | 32 | 40000000 | 0 | 10000000 | 00000000000000000000000 |
| 3.14 | 32 | 4048f5c3 | 0 | 10000000 | 10010001111010111000011 |
| -2.5 | 32 | c0200000 | 1 | 10000000 | 01000000000000000000000 |
| -1 | 32 | bf800000 | 1 | 01111111 | 00000000000000000000000 |
| 0.25 | 32 | 3e800000 | 0 | 01111101 | 00000000000000000000000 |
| 100 | 32 | 42c80000 | 0 | 10000101 | 10010000000000000000000 |
| 0.001 | 32 | 3a83126f | 0 | 01110101 | 00000110001001001101111 |
| 1 | 64 | 3ff0000000000000 | 0 | 01111111111 | 0000000000000000000000000000000000000000000000000000 |
| 0.1 | 64 | 3fb999999999999a | 0 | 01111111011 | 1001100110011001100110011001100110011001100110011010 |
整数也有自己的位表达,只是没有指数与尾数之分:255 的二进制是 11111111(8 位),1024 是 10000000000(11 位),65535 是 1111111111111111(16 位),65536 是 10000000000000000(17 位)。整数每多一位就多一倍的取值范围,浮点则把位分给了指数与尾数,这是两者最根本的区别。
| 十进制整数 | 最少位宽 | 二进制 |
|---|---|---|
| 0 | 1 | 0 |
| 1 | 1 | 1 |
| 255 | 8 | 11111111 |
| 1024 | 11 | 10000000000 |
| 65535 | 16 | 1111111111111111 |
| 65536 | 17 | 10000000000000000 |
把这两张表对着看,能看清浮点到底省掉了什么:整数 65535 用 16 位就能精确表示,而双精度用了 64 位,换来的不是「把 65535 存得更准」,而是能同时表示 0.0000001 与 10000000000 这种跨度极大的数。代价是精度按有效位分配:数值越大,相邻两个可表示的数之间隔得越远,超过 2 的 53 次方的整数就已经无法逐个区分了。所以金额、计数这类要求分毫不差的场景不该用浮点,而科学计算、图形与信号处理恰恰需要这种「范围换精度」的设计。
结果边界、舍入与适用说明
- 数值栏留空时点「开始转换」会自动填回 0.1;写成非数字会给出提示并说明应填十进制数。
- Infinity 与 -Infinity 被当成合法输入,位型是「指数全 1 + 尾数全 0」;NaN 无法由十进制字面量输入,本页不提供入口。
- 指数段全 0 时按非规格化数与零处理,隐含前导位为 0,真实指数按 −1022(双精度)或 −126(单精度)计,与规格化数的算法不同。
- 32 位单精度的回读值是真值在双精度里的展开,所以 3.14 会读成 3.140000104904175,这不是算错,而是单精度只有 24 位有效精度。
- 本页给出的位串是大端序(符号在前、指数居中、尾数在后),与小端序的内存字节排列不是一回事,比对接包数据时要注意字节序。
- 十六进制一律小写、不足补零:32 位 8 个字符,64 位 16 个字符,不随数值大小变化。
- 位布局表固定 20 项,不随输入变化,也不联网扩展;表里数值都是十进制字面量,不是计算出来的近似。
- 页面不上传数据、不写本地存储;导出的 CSV 带字节序标记,Excel 打开不乱码。
常见问题
为什么 0.1 存进去不是精确的 0.1?
0.1 换成二进制是 0.0001100110011……,1001 无限循环。双精度只留 52 位尾数,第 53 位按舍入进位,于是存的是比 0.1 略大一点的值。
0.1 + 0.2 为什么不等于 0.3?
因为 0.1 与 0.2 都是被截断过的近似值,相加后误差累积,得到的是 0.30000000000000004,而 0.3 又是另一个近似值,两者不相等。
指数为什么不用补码?
偏移码让指数段的大小顺序与真实指数一致,两个浮点数可以直接按整数比较大小;补码做不到这一点。双精度偏差是 1023,单精度是 127。
尾数为什么少一位?
规格化数的整数部分恒为 1,标准把这个 1 省掉不存,只存小数部分。所以 52 位尾数实际提供 53 位精度,23 位实际提供 24 位。
32 位和 64 位差多少?
指数从 8 位变 11 位,尾数从 23 位变 52 位。有效精度从约 7 位十进制涨到约 16 位,取值范围也大幅扩大。
回读值和输入不一样,是算错了吗?
不是。切到 32 位时,数值先被舍入到单精度再回读,3.14 会读成 3.140000104904175,这正是单精度的精度上限。
位串的顺序和内存里的字节一样吗?
不一定。本页按大端位序书写(符号、指数、尾数),内存字节还受处理器的字节序影响,小端机器上字节顺序是反的。
输入的数据会上传到服务器吗?
不会。转换、查表与导出都在本页完成,没有发起任何网络请求,也不写入浏览器存储,刷新页面即恢复默认值。
相关工具
- 十进制转二进制转换器:整数的二进制表达,与本页的浮点位布局互为补充。
- 二进制转十进制转换器:把位串折回十进制,反向核对本页的输出。
- 数字进制转换器:二、八、十、十六进制之间任意互转,含小数部分。
- 十进制转十六进制转换器:只要十六进制、不用看位串时用这一页。
- 二进制计算器:直接在二进制上做加减乘除,看完位串再动手算。
- 开发者工具:查看全部开发者工具。