为什么JavaScript中带小数的最大位数只有16 [英] Why max digits with decimal in JavaScript are only 16
问题描述
前一段时间,当我测试某些HTML表单时遇到了这个问题. JavaScript Number中带有小数点的最大位数仅为16
I came across this issue a while back when I was testing some HTML forms. The Maximum number of digits in JavaScript Number with a decimal point is only 16
我尝试了以下
var x = 12345678912345.6789
x是12345678912345.68-仅16位数字
x is 12345678912345.68 - 16 Digits only
var x = 123456789123.6789
x是123456789123.6789-仅16位数字
x is 123456789123.6789 - 16 Digits only
new Number(12345678912345.6789)
12345678912345.68-仅16位
12345678912345.68 - 16 Digits only
new Number(123456789123.6789)
123456789123.6789-仅16位
123456789123.6789 - 16 Digits only
如果计算总位数,则为16.如果增加小数点前的位数,则将小数点后的位数四舍五入
if you count the total digits, they are 16. If you increase digits before decimal point, the digits after decimal point get rounded
类似地
new Number(.12345678912367890)
是0.1234567891236789-仅16位(注意尾随0缺失)
is 0.1234567891236789 - 16 Digits only (notice trailing 0 is missing)
这让我推断出我的数字中只能有16位数字,其中包含小数.如果我尝试添加更多数字,数字开始四舍五入
Which makes me deduce that I can only have 16 Digits in a number with Decimal in it. If I try to add more digits, the number starts to round
我还观察到,当我在ASP.NET MVC中将带小数的数字序列化为JSoN时,它还会将数字转换为最大16位数字,并四舍五入
I also observed that when I serialize a number with decimal into JSoN in ASP.NET MVC, it also converts the number to Max 16 Digits and rounds the rest
我的问题:为什么?
推荐答案
According to JS/ECMAScript specification, the Number
type uses double-precision floating point which has 64-bit format (binary64
), consists of a sign bit (determines positive or negative value), 11 exponent bits and 52 fraction bits (each digit represents 4-bits, hence 64-bit has 16 digits):
代表双精度64位格式IEEE的Number类型 IEEE二进制标准中指定的754-2008值 浮点算法.
The Number type representing the double-precision 64-bit format IEEE 754-2008 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic.
可以使用双精度正确表示的最大正数是9007199254740992
,可以通过使用Math.pow(2, 53)
来实现.如果数字范围在Math.pow(2, 53)
和Math.pow(2, 54)
之间(或在Math.pow(2, -53)
和Math.pow(2, -54)
之间),则只能正确地表示偶数,因为指数位会影响小数位的LSB(最低有效位).
The maximum positive number which can be represented properly using double precision is 9007199254740992
, which can be achieved by using Math.pow(2, 53)
. If the number range is between Math.pow(2, 53)
and Math.pow(2, 54)
(or between Math.pow(2, -53)
and Math.pow(2, -54)
), only even numbers can be represented properly because the exponent bits will affect LSB (least-significant bit) on the fraction bits.
让我们回顾大量部分:
var x = 12345678912345.6789
var x = new Number(12345678912345.6789)
该数字包含52个以上的小数位(总共72个位),因此用于将小数位保持为52的舍入.
This number contains more than 52 fractional bits (72 bits in total), hence the rounding used to keep the fractional bits to 52.
也使用此十进制数字:
var x = new Number(.12345678912367890)
该数字包含68个小数位,因此最后一个零被切掉以保持64位长度.
This number contains 68 fractional bits, hence the last zero is chopped off to keep 64-bit length.
通常,大于9007199254740992
或小于1.1102230246251565E-16
的数字表示形式将存储为文字字符串而不是Number
.如果需要计算非常大的数字,则可以使用某些外部库来执行任意精度算术.
Usually numeric representation larger than 9007199254740992
or smaller than 1.1102230246251565E-16
are stored as literal strings instead of Number
. If you need to compute very large numbers, there are certain external libraries available to perform arbitrary precision arithmetic.
进一步阅读:
这篇关于为什么JavaScript中带小数的最大位数只有16的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!