【问题标题】:Why console.log shows only part of the number resulting from 0.1+0.2=0.30000000000000004为什么console.log只显示0.1+0.2=0.30000000000000004产生的部分数字
【发布时间】:2016-05-20 15:26:12
【问题描述】:

这个问题还没有在 stackoverlow 上问过!我不是在问为什么 0.1+0.2 不等于 0.3,我问的是非常不同的事情!请在将其标记为重复之前阅读该问题。


我编写了这个函数来展示 JavaScript 如何以 64 位存储浮点数:

function to64bitFloat(number) {
    var f = new Float64Array(1);
    f[0] = number;
    var view = new Uint8Array(f.buffer);
    var i, result = "";
    for (i = view.length - 1; i >= 0; i--) {
        var bits = view[i].toString(2);
        if (bits.length < 8) {
            bits = new Array(8 - bits.length).fill('0').join("") + bits;
        }
        result += bits;
    }
    return result;
}

现在我想检查0.1+0.2 的结果是否实际存储为控制台0.30000000000000004 中显示的那样。所以我做了以下事情:

var r = 0.1+0.2;
to64bitFloat(r);

得到的数字是:

0 01111111101 0011001100110011001100110011001100110011001100110100

现在,让我们将其转换为二进制:

计算的指数:

01111111101 = 1021
1021 - 1023 = -2 

把它放在一起,

1.0011001100110011001100110011001100110011001100110100 x 2 ** -2 =
0.010011001100110011001100110011001100110011001100110100

现在,如果我们使用this converter 将结果数字转换为十进制,我们得到:

0.3000000000000000444089209850062616169452667236328125

为什么控制台不显示整数,而只是显示更多有效数字?

【问题讨论】:

标签: javascript binary ieee-754


【解决方案1】:

console.log 方法是非标准的。在 Firefox 中,您可以使用 format specifier 指定小数位数

console.log('%.60f', 0.1 + 0.2)

给予

0.300000000000000044408920985006261616945266723632812500000000

与转换器给出的数字相同。

请注意,这在 chrome 中不起作用。

总结:

  • Javascript 数字以 IEEE 754-2008 双精度 64 位二进制格式存储。
  • 数字的字符串表示在ECMAScript standard 中定义。
  • console.log 方法取决于浏览器,Firefox 实现允许指定任意小数位数来显示数字。

【讨论】:

  • 这是最大精度,我们可以得到我使用我的函数最终得到的数字吗?
  • 酷,谢谢。您能否在回答中总结thisthis 评论中的人所说的内容。我会接受你的回答
【解决方案2】:

其实你不必写这么长的问题。你可以做的就是打开控制台并输入:

var a = 0.3000000000000000444089209850062616169452667236328125;

console.log(a);

这仍然会给你结果 - 0.30000000000000004(至少在 Google chrome 控制台中)。

之所以会这样,是因为 JS 的限制,它只允许显示 16 个字符的浮点数。您可以阅读更多内容来回答这个问题:https://stackoverflow.com/a/19613321/3014041

【讨论】:

  • 您链接到的答案是错误的。双精度有 52 个有效数字,而不是 16
  • 请阅读 wiki - en.wikipedia.org/wiki/Double-precision_floating-point_format,它是 52 位,提供 15-17 位有效十进制数字精度。
  • 那时我们可能在谈论不同的事情
  • 我认为我们确实在谈论不同的事情。你是说 JavaScript 在 base-10 系统中显示时不能显示超过 17 位 小数点?
  • @naneri 双打有 53 位(它在您链接的文档中说)。
猜你喜欢
  • 1970-01-01
  • 2014-05-05
  • 2011-11-24
  • 2011-10-16
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多