【问题标题】:Why addition lose precision when direct assignment works for Javascript number data type? [duplicate]当直接赋值适用于 Javascript 数字数据类型时,为什么加法会丢失精度? [复制]
【发布时间】:2021-12-10 15:07:51
【问题描述】:

考虑一个简单的代码sn-p:

let a = 0.1;
let b = 0.2;
let c = 0.3;
let d = a + b;

console.log(c.toString()); //0.3
console.log(d.toString()); //0.30000000000000004

我能找到的解释是0.3 不能用双精度浮点数精确表示。但如果这是真的,c 如何在不丢失精度的情况下保持0.3 的值在直接赋值的情况下

【问题讨论】:

    标签: javascript floating-point double


    【解决方案1】:

    两者都无法精确表示。使用this converter 看看发生了什么。

    JavaScript 数字表示为双精度 64 位数字 (IEEE754)

    0.3 单独gets interpreted as0x3FD3333333333333,也就是说,如果你手头计算的话:

    .299999999999999988897769753748...
    

    当显示为小数时,将四舍五入为 0.3。并不是存储的值恰好等于 0.3(如果您尝试使用它进行更多计算,可以显示),而是显示时,它显示为 0.3 - 它比下一位更接近 3,这是2.9999999999999993

    0.1 + 0.2 偏移了一点 - 最后一位(十六进制)is 4, not 30x3FD3333333333334 是:

    .300000000000000044408920985006...
    

    同样,您不能将 0.300000000000000002 用于直接赋值或直接记录,因为它位于两个位之间,解释器必须选择其中之一:

    console.log(0.30000000000000002);

    【讨论】:

    • 谢谢。这确实有道理。是什么让toString.2999999999999999888 显示为0.3.3000000000000000444... 显示为.30000000000000004
    • 我也想知道。我原以为 .299999999999999989(超过显示精度点)将四舍五入以显示为 0.29999999999999999(17 位小数,就像 .30000000000000004 一样),但它显示为 0.3。也许这些类型的数字没有更接近偶数十进制数的表示(例如 0.3、0.257 等)显示为 该十进制数,因为这些小数更有可能是“准确”的感知由编剧作为技术上更精确的数字,带有很多尾随数字。
    • IOW: "对于可以表示的最接近 0.3 的数字,我们应该显示 0.3 还是更精确的扩展十进制数?"看起来他们选择显示 0.3 - 其他十进制数也是如此。
    • 有趣。但是为什么同样的论点也不能应用于.299999999999999989 并显示为0.3?我在 .NET/C# 中也看到了同样的行为。也许也有显示值的标准?
    • 可能是因为 .299999999999999989 在引擎中表示时与 .3 表示的值无法区分。是的,可能有一个显示标准或通用算法或类似的东西。
    猜你喜欢
    • 2018-07-22
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2012-07-25
    • 1970-01-01
    • 2019-10-23
    相关资源
    最近更新 更多