为什么console.log只显示0.1+0.2=0.30000000000000004得到的部分数字

问题描述 投票:0回答:2

我编写了这个函数,展示了 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

现在,如果我们使用这个转换器将结果数字转换为十进制,我们会得到:

0.3000000000000000444089209850062616169452667236328125

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

注意可能的重复

我不是问为什么 0.1+0.2 不等于 0.3,我问的是完全不同的事情。

javascript binary ieee-754
2个回答
4
投票

console.log方法是非标准的。在 Firefox 中,您可以使用 格式说明符

指定小数位数
console.log('%.60f', 0.1 + 0.2)

给予

0.300000000000000044408920985006261616945266723632812500000000

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

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

总结:

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

2
投票

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

var a = 0.3000000000000000444089209850062616169452667236328125;

console.log(a);

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

之所以会这样,是因为JS的限制,只能显示一个float的16个字符。您可以阅读此问题的更多答案:https://stackoverflow.com/a/19613321/3014041

© www.soinside.com 2019 - 2024. All rights reserved.