JS如何将大数(2 ^ 53以上)转换为字符串

时间:2018-07-24 15:32:55

标签: javascript double

由于2 ^ 53以上的整数不能精确地以双精度表示,因此JS在将其打印为字符串时如何确定其小数表示形式?

例如,2 ^ 55是36028797018963968,C中的printf("%lf",(double)(1LL<<55))将正确打印该数字,因为它的二进制表示形式具有尾随零,在被截断时不会引起精度损失。

但是,在Javascript中,我们改为获取36028797018963970。似乎尝试对数字进行四舍五入以获得结尾处的0,但并非总是如此-例如,正确地将2 ^ 55-4表示为4。

规范中是否有定义这种奇怪行为的地方?

1 个答案:

答案 0 :(得分:1)


问题-由于2 ^ 53以上的整数不能精确地以双精度表示,因此JS在打印为字符串时如何确定小数表示形式?



1.在JS中打印小数的方法

JavaScript数字内部存储在二进制浮点中,通常以十进制显示。

JavaScript使用两种十进制表示法:

固定符号

[ "+" | "-" ] digit+ [ "." digit+ ]

指数符号

[ "+" | "-" ] digit [ "." digit+ ] "e" [ "+" | "-" ] digit+

指数表示法的一个示例是1.2345678901234568e+21

显示十进制数字的规则:

A。。如果小数点前有超过21位数字,请使用指数表示法。

B。。如果数字以“ 0”开头,然后是五个以上的零,请使用指数表示法。


2. ECMAScript 5.1显示算法

以下是Sect的详细信息。 ECMAScript 5.1规范的9.8.1描述了显示十进制数字的算法

给出一个数字

mantissa × 10^pointPos−digitCount
  

浮点数的尾数是一个整数-有效数字加一个符号。前导零和尾随零将被丢弃。例子:   12.34的尾数为1234。

案例1。 无小数点: digitCount ≤ pointPos ≤ 21 打印数字(不带前导零),然后打印pointPos-digitCount零。

情况2。 尾数内的小数点0 < pointPos ≤ 21, pointPos < digitCount 显示尾数的pointPos前一位数字,一个点,然后显示其余digitCount-pointPos位。

情况3。 小数点位于尾数之前−6 < pointPos ≤ 0 显示0,后跟一个点,-pointPos零和尾数。

案例4。 指数表示法pointPos ≤ -6 or pointPos > 21 显示尾数的第一位数字。如果还有更多数字,请显示一个点和剩余的数字。接下来,显示字符e和一个加号或减号(取决于pointPos-1的符号),然后显示pointPos-1的绝对值。因此,结果如下所示。

mantissa0 [ "." mantissa1..digitCount ] 
     "e" signChar(pointPos−1) abs(pointPos−1)

问题- 但是,在Javascript中,我们改为获取36028797018963970。似乎尝试对数字进行四舍五入以获得结尾处的0,但并非总是如此-例如,正确地将2 ^ 55-4表示为4。

规范中是否有定义这种奇怪行为的地方?



检查:How numbers are encoded in JavaScript特别是==> 5。最大整数


其他参考: https://medium.com/dailyjs/javascripts-number-type-8d59199db1b6