为什么 JavaScript 中带有十进制的最大数字只有 16



我在测试一些HTML表单时遇到了这个问题。JavaScript 中带小数点的数字的最大位数仅为 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 位数字。如果我尝试添加更多数字,数字开始四舍五入

我还观察到,当我在 MVC 中将带有十进制的数字序列化为 JSoN 时 ASP.NET 它还会将该数字转换为最多 16 位数字并将其余数字四舍五入

我的问题:为什么?

根据 JS/ECMAScript 规范,Number类型使用双精度浮点,该浮点具有 64 位格式 (binary64),由一个符号位(确定正值或负值)、11 个指数位和 52 个分数位(每个数字代表 4 位,因此 64 位有 16 位

):

表示双精度 64 位格式 IEEE 的数字类型 IEEE 二进制标准中规定的 754-2008 值浮点运算。

使用双精度可以正确表示的最大正数是9007199254740992,这可以通过使用Math.pow(2, 53)来实现。如果数范围介于Math.pow(2, 53)Math.pow(2, 54)之间(或介于Math.pow(2, -53)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。如果需要计算非常大的数字,则可以使用某些外部库来执行任意精度的算术。

延伸阅读:

ECMAScript:数字编码

ECMAScript:处理大整数

在 javascript 中,你不能用二进制浮点类型精确地表示大多数小数部分(这是 ECMAScript 用来表示浮点值的)。

这就是为什么javascript在小数点后使用16个数字。 例如-

尝试运行:

var x =  3.14159265358979323846;
print(x.toFixed(20));

并看到以下内容正在浮动。

如果要在小数点后投射超过 16 位,您可以:

  • 使用文字字符串表示您的数字
  • 使用外部库,如 math.js 或 BigInteger.js。

相关内容

  • 没有找到相关文章

最新更新