javascript - JavaScript 是如何以如此精确的方式打印 0.1 的呢?

标签 javascript floating-point ieee-754

我已经heard javascript 数字是 IEEE 754 float ,这解释了为什么

> 0.3 - 0.2
0.09999999999999998

但是我不明白

> 0.1
0.1

我认为 0.1 无法准确地存储为以 2 为基数的 float ,但它会立即打印出来,就像它一直是 0.1 一样。是什么赋予了?解释器在打印之前是否进行了一些舍入?

至少有 2 个版本的 IEEE 754:1984 对我没有帮助版和2008 。听起来后者添加了 full support for decimal arithmetic 。我们好像没有这个啊

最佳答案

JavaScript 使用 IEEE-754 double 字(2008 年规范中的“binary64”;也就是说,正如您所怀疑的那样,它是 Base 2 版本,而不是 2008 年 Base 10 版本)。

尽管 0.1 无法完美地以二进制 64 表示,但您获得数字值 0.1 的字符串 "0.1" 的原因,是不是——

TL;DR:该字符串不是数字的精确版本,它只是足够精确以将其与其相邻的不太精确的数字区分开来。确切数字

——该规范定义了将数字转换为字符串的复杂规则,以解决精度不足的问题。它们包含在 §9.8.1 - ToString Applied to the Number Type 中:

  1. If m is NaN, return the String "NaN".
  2. If m is +0 or −0, return the String "0".
  3. If m is less than zero, return the String concatenation of the String "-" and ToString(−m).
  4. If m is infinity, return the String "Infinity".
  5. Otherwise, let n, k, and s be integers such that k ≥ 1, 10k−1 ≤ s < 10k, the Number value for s × 10n−k is m, and k is as small as possible. Note that k is the number of digits in the decimal representation of s, that s is not divisible by 10, and that the least significant digit of s is not necessarily uniquely determined by these criteria.
  6. If kn ≤ 21, return the String consisting of the k digits of the decimal representation of s (in order, with no leading zeroes), followed by n−k occurrences of the character ‘0’.
  7. If 0 < n ≤ 21, return the String consisting of the most significant n digits of the decimal representation of s, followed by a decimal point ‘.’, followed by the remaining k−n digits of the decimal representation of s.
  8. If −6 < n ≤ 0, return the String consisting of the character ‘0’, followed by a decimal point ‘.’, followed by −n occurrences of the character ‘0’, followed by the k digits of the decimal representation of s.
  9. Otherwise, if k = 1, return the String consisting of the single digit of s, followed by lowercase character ‘e’, followed by a plus sign ‘+’ or minus sign ‘−’ according to whether n−1 is positive or negative, followed by the decimal representation of the integer abs(n−1) (with no leading zeroes).
  10. Return the String consisting of the most significant digit of the decimal representation of s, followed by a decimal point ‘.’, followed by the remaining k−1 digits of the decimal representation of s, followed by the lowercase character ‘e’, followed by a plus sign ‘+’ or minus sign ‘−’ according to whether n−1 is positive or negative, followed by the decimal representation of the integer abs(n−1) (with no leading zeroes).

然后有以下注释;请点击链接了解完整详细信息。注 3 可能是最相关的:

NOTE 3

Implementers of ECMAScript may find useful the paper and code written by David M. Gay for binary-to-decimal conversion of floating-point numbers:

Gay, David M. Correctly Rounded Binary-Decimal and Decimal-Binary Conversions. Numerical Analysis, Manuscript 90-10. AT&T Bell Laboratories (Murray Hill, New Jersey). November 30, 1990. Available as http://cm.bell-labs.com/cm/cs/doc/90/4-10.ps.gz. Associated code available as http://cm.bell-labs.com/netlib/fp/dtoa.c.gz and as http://cm.bell-labs.com/netlib/fp/g_fmt.c.gz and may also be found at the various netlib mirror sites.

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

关于javascript - JavaScript 是如何以如此精确的方式打印 0.1 的呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48433074/

相关文章:

c# - 我如何每 x 秒使用 javascript 调用一个 C# 函数?

javascript - Safari 显示的字体与其他浏览器不同 - 为特定浏览器设置特定字体系列 - 如何更改 Safari 的字体平滑

c# - 如何将 NUnit 的 EqualTo().Within() 约束与自定义数据类型一起使用?

c++ - 用于存储简单小数值的浮点替代方案

python - 具有 dtype float 的 Numpy n 元组数组

c - 以 IEEE 754 交换格式记录/读取 C double

javascript - 向 slider 添加自定义箭头

javascript - 使用 Selenium 和 python 抓取 javascript 生成的内容时出现问题

floating-point - 可以影响 double 的最大十进制位数

c - 关于 IEEE 754、64 位双倍的问题?