javascript如何以如此精确的方式打印0.1?

javascript如何以如此精确的方式打印0.1?,javascript,floating-point,ieee-754,Javascript,Floating Point,Ieee 754,我发现javascript数字是浮点数,这就解释了为什么 > 0.3 - 0.2 0.09999999999999998 但我不明白 > 0.1 0.1 我原以为0.1不能准确地存储为基数为2的浮点,但它会直接打印出来,就像一直是0.1一样。有什么好处?翻译在打印前是否进行了取整 IEEE 754至少有两个版本:版本和。听起来像是后者补充说的。好像我们没有 JavaScript使用IEEE-754双精度数字(“binary64”,正如2008年规范所说;也就是说,正如您所怀疑的,

我发现javascript数字是浮点数,这就解释了为什么

> 0.3 - 0.2
0.09999999999999998
但我不明白

> 0.1
0.1
我原以为0.1不能准确地存储为基数为2的浮点,但它会直接打印出来,就像一直是0.1一样。有什么好处?翻译在打印前是否进行了取整


IEEE 754至少有两个版本:版本和。听起来像是后者补充说的。好像我们没有

JavaScript使用IEEE-754双精度数字(“binary64”,正如2008年规范所说;也就是说,正如您所怀疑的,它是base 2版本,而不是2008 base 10版本)

对于数值
0.1
,即使
0.1
不能在binary64中完美表示,也会得到字符串
“0.1”
,原因是-

TL;DR:字符串不是数字的精确版本,它只是精确到足以将其与相邻的不完全精确的数字区分开来

-该规范定义了将数字转换为字符串的复杂规则,以解决精度的不足。它们包含在:

  • 如果m是NaN,则返回字符串“NaN”
  • 如果m是+0−0,返回字符串“0”
  • 如果m小于零,则返回字符串“-”和ToString的字符串串联(−m)
  • 如果m是无穷大,则返回字符串“infinity”
  • 否则,设n,k,s为整数,使得k≥ 110K−1.≤ s<10k,s×10n的数值−k是m,k尽可能小。注意,k是s的十进制表示中的位数,s不能被10整除,s的最低有效位不一定由这些标准唯一确定
  • 如果k≤ N≤ 21,返回由s的十进制表示形式的k位(按顺序,无前导零)组成的字符串,后跟n−字符'0'的k次出现次数
  • 如果0,后跟剩余的k−s的十进制表示形式的n位
  • 如果−6'0'组成的字符串,后跟小数点,后跟−n个字符'0',后跟s的十进制表示形式的k位
  • 否则,如果k=1,则返回由s的单个数字组成的字符串,后跟小写字符'e',后跟加号'+'或减号'−’根据n−1为正或负,后跟整数abs(n)的十进制表示形式−1) (没有前导零)
  • 返回由s的十进制表示形式的最高有效位组成的字符串,后跟一个小数点。。,后跟剩余的k−s的十进制表示形式的1位数字,后跟小写字符'e',后跟加号'+'或减号'−’根据n−1为正或负,后跟整数abs(n)的十进制表示形式−1) (没有前导零)
  • 然后是以下注释;请按照链接了解完整的详细信息。注3可能是最相关的:

    注3

    ECMAScript的实现者可能会发现David M.Gay编写的关于浮点数从二进制到十进制转换的论文和代码很有用:

    Gay,David M.正确地舍入了二进制十进制和十进制二进制转换。数值分析,手稿90-10。AT&T贝尔实验室(新泽西州默里山)。1990年11月30日。可用作 . 相关代码如下所示: 作为 也可以在各种netlib镜像站点上找到


    对我来说,4-10.ps.gz文件似乎已损坏(无法阅读第6-8页),但我在这里找到了一个PDF:(不是像看起来那样随机的链接,显然是本文工作的主要动机)。

    除非您使用IBM POWER architecture,否则您不太可能在野外看到IEEE小数64。不幸的是,据我所知,二进制浮点十进制打印的最新技术是Florian Loitsch的“grisu算法”:@SimonByrne:非常酷。ECMA规范可能应该走Java路线,而不是如此规范。Java文档“m或a的小数部分必须打印多少个数字?必须至少有一个数字来表示小数部分,除此之外,还必须有足够多的数字来唯一区分参数值与
    double
    类型的相邻值。”然后说如果是平局,顺便说一句,两个“最近的”NUM,选择一个偶数。:-)