javascript如何以这样的准确度打印0.1?

hur*_*lad 5 javascript floating-point ieee-754

听说 javascript数字是IEEE 754浮点数,这就解释了原因

> 0.3 - 0.2
0.09999999999999998
Run Code Online (Sandbox Code Playgroud)

但我不明白

> 0.1
0.1
Run Code Online (Sandbox Code Playgroud)

我认为0.1无法准确地存储为基础2浮点,但它会向后打印,就像它一直是0.1.是什么赋予了?解释器打印之前是否进行了一些舍入?

至少有两个版本的IEEE 754:1984版本和2008年,这对我没有帮助.听起来后者增加了对十进制算术的完全支持.似乎我们没有.

T.J*_*der 10

JavaScript使用IEEE-754双精度数字("binary64"作为2008规范提出来;也就是说,正如您所怀疑的那样,它是基础2版本,而不是2008年基础10版本).

你获得"0.1"数字值的字符串的原因0.1,即使0.1无法在binary64中完美呈现,是 -

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

- 规范定义了将数字转换为字符串的复杂规则,以解决缺乏精确性的问题.它们包含在§9.8.1中 - ToString应用于数字类型:

  1. 如果mNaN,则返回字符串"NaN".
  2. 如果m+0-0,则返回字符串"0".
  3. 如果m小于零,则返回字符串" - "和ToString( - m)的字符串串联.
  4. 如果m为无穷大,则返回字符串"Infinity".
  5. 否则,设Ñ,ķ,和小号是整数,使得ķ≥1,10 k-1个 ≤S <10的ķ,对于s Number值×10 N-K,并且ķ是尽可能小.注意,ks的十进制表示中的位数,s不能被10整除,并且s的最低有效位不一定由这些标准唯一确定.
  6. 如果ķÑ ≤21,返回自由以下组成的字符串ķ的十进制表示的数字小号(按顺序,没有前导零),其次是n-k个字符的出现"0".
  7. 如果0 <n≤21,则返回由s的十进制表示的最高n位数组成的字符串,后跟小数点'.' ,后跟s的十进制表示的剩余k-n个数字.
  8. 如果-6 <n≤0,则返回由字符"0"组成的字符串,后跟小数点"." ,然后是-n出现的字符'0',后跟s的十进制表示的k个数字.
  9. 否则,如果k = 1,则返回由s的单个数字组成的字符串,后跟小写字符"e",后跟加号'+'或减号' - ',根据n -1是正还是负,后跟整数abs(n -1)的十进制表示(没有前导零).
  10. 返回由s的十进制表示的最高有效位组成的字符串,后跟小数点'.' ,其次是s的十进制表示的剩余k -1个数字,后跟小写字母'e',后跟加号'+'或减号' - ',根据n -1是正还是负,后跟整数abs(n -1)的十进制表示(没有前导零).

然后有以下注释; 点击链接了解完整详情.注3可能是最相关的:

注3

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

Gay,David M.正确地舍入二进制 - 十进制和十进制 - 二进制转换.数值分析,手稿90-10.AT&T贝尔实验室(新泽西州默里山).1990年11月30日.提供 http://cm.bell-labs.com/cm/cs/doc/90/4-10.ps.gz.相关代码可以 http://cm.bell-labs.com/netlib/fp/dtoa.c.gzhttp://cm.bell-labs.com/netlib/fp/g_fmt.c.gz和也可以在各种netlib镜像站点找到.

对我来说,4-10.ps.gz文件似乎已损坏(无法阅读第6-8页),但我在这里找到了一个PDF:http://ampl.com/REFS/rounding.pdf(不是随机链接看起来很可能,显然AMPL是本文工作的主要动机).