为什么JavaScript中带小数的最大位数只有16

时间:2019-02-21 05:44:37

标签: javascript asp.net-mvc json.net precision

前一段时间,当我测试某些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时,它还会将数字转换为最大16位数字,并对其余部分四舍五入

我的问题:为什么?

2 个答案:

答案 0 :(得分:1)

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

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

尝试运行:

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

,然后看到以下内容正在浮起。

如果您想在小数点后再投射16点,则可以:

答案 1 :(得分:1)

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

  

代表双精度64位格式IEEE的Number类型   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: Number Encoding

ECMAScript: Working with large integers