javascript - 为什么 JavaScript 中带小数的最大位数只有 16
问题描述
不久前我在测试一些 HTML 表单时遇到了这个问题。JavaScript Number 中带小数点的最大位数只有 16
我试过以下
var x = 12345678912345.6789
x 为 12345678912345.68 -仅 16 位
var x = 123456789123.6789
x 是 123456789123.6789 -仅 16 位
new Number(12345678912345.6789)
12345678912345.68 -仅 16 位
new Number(123456789123.6789)
123456789123.6789 -仅 16 位
如果计算总位数,则为 16。如果增加小数点前的位数,则小数点后的位数会四舍五入
相似地
new Number(.12345678912367890)
为 0.1234567891236789 -仅 16 位(注意缺少尾随 0)
这让我推断我只能有 16 位数字,其中包含十进制。如果我尝试添加更多数字,则数字开始四舍五入
我还观察到,当我在 ASP.NET MVC 中将带小数的数字序列化为 JSoN 时,它还会将该数字转换为 Max 16 Digits 并将其余的四舍五入
我的问题:为什么?
解决方案
根据 JS/ECMAScript 规范,该Number
类型使用双精度浮点,具有 64 位格式binary64
(位,因此 64 位有 16 位):
表示双精度 64 位格式 IEEE 754-2008 值的数字类型,如 IEEE 二进制浮点算术标准中指定的那样。
使用双精度可以正确表示的最大正数是9007199254740992
,可以通过使用 来实现Math.pow(2, 53)
。如果数字范围在Math.pow(2, 53)
and之间Math.pow(2, 54)
(或介于Math.pow(2, -53)
and之间Math.pow(2, -54)
),则只能正确表示偶数,因为指数位会影响小数位上的 LSB(最低有效位)。
让我们回顾一下大数部分:
var x = 12345678912345.6789
var x = new Number(12345678912345.6789)
该数字包含超过 52 个小数位(总共 72 位),因此用于将小数位保持为 52 的舍入。
还有这个十进制数:
var x = new Number(.12345678912367890)
这个数字包含 68 个小数位,因此最后一个零被切掉以保持 64 位长度。
通常大于9007199254740992
或小于1.1102230246251565E-16
的数字表示存储为文字字符串而不是Number
. 如果您需要计算非常大的数字,可以使用某些外部库来执行任意精度算术。
进一步阅读:
推荐阅读
- css - 如何在反应中的两个列表项之间切换类名
- python - 如何调用另一个 python 文件,运行它,并将 main.py 替换为新的 .py 文件?
- c++ - 在C++中设计promote()机制的正确方法是什么
- kml - 谷歌 KML 文件到 python
- react-native - 如何在 React Native 中检查滚动视图是否已到达顶部?
- mysql - MySQL 错误代码:'ER_DBACCESS_DENIED_ERROR'
- rust - 如何检测是否启用了不稳定的功能?
- laravel - $bucket 无法识别的选项:$group
- series - 将系列转换为固定值松脚本
- flutter - 处理 FCM 数据消息颤动的背景点击