我有以下虚拟测试脚本:

函数测试(){变量x=0.1*0.2;document.write(x);}测试();

这将打印结果0.020000000000000004,而它应该只打印0.02(如果您使用计算器)。据我所知,这是由于浮点乘法精度的错误。

有没有人有一个好的解决方案,在这种情况下,我得到了正确的结果0.02?我知道还有一些函数,比如toFixed或舍入,这是另一种可能,但我真的希望在不进行任何切割和舍入的情况下打印整个数字。我只是想知道你们中的一个人是否有一些好的、优雅的解决方案。

当然,否则我会舍入到10位数左右。


当前回答

你只是在做乘法吗?如果是这样的话,那么你可以利用一个关于十进制算术的简单秘密。即NumberOfDecimals(X)+NumberOfDecimals(Y)=预期的NumberOf小数。也就是说,如果我们有0.123*0.12,那么我们知道会有5位小数,因为0.123有3位小数,0.12有2位小数。因此,如果JavaScript给我们一个像0.014760000002这样的数字,我们可以安全地四舍五入到小数点后的第五位,而不用担心丢失精度。

其他回答

你只是在做乘法吗?如果是这样的话,那么你可以利用一个关于十进制算术的简单秘密。即NumberOfDecimals(X)+NumberOfDecimals(Y)=预期的NumberOf小数。也就是说,如果我们有0.123*0.12,那么我们知道会有5位小数,因为0.123有3位小数,0.12有2位小数。因此,如果JavaScript给我们一个像0.014760000002这样的数字,我们可以安全地四舍五入到小数点后的第五位,而不用担心丢失精度。

不优雅,但能完成任务(删除尾随零)

var num = 0.1*0.2;
alert(parseFloat(num.toFixed(10))); // shows 0.02

我通常用这样的东西。

function pf(n) {
    return Math.round(n * 1e15) / 1e15;
}

我并不认为这在任何方面都是最佳的,但我喜欢它的简单性。它将数字四舍五入到小数点后15位左右。我没有看到它返回不准确的浮点数,但奇怪的是,当我在末尾使用*1e-15时,它已经这样做了,但没有使用这种方法。

这种解决方案可能更适合于随意使用,而不是精确的数学使用,因为精确错误会扰乱代码。

我不太擅长编程,但对这个主题很感兴趣,所以我试图了解如何在不使用任何库或脚本的情况下解决这个问题

我在草稿栏上写的

var toAlgebraic = function(f1, f2) {
    let f1_base = Math.pow(10, f1.split('.')[1].length);
    let f2_base = Math.pow(10, f2.split('.')[1].length);
    f1 = parseInt(f1.replace('.', ''));
    f2 = parseInt(f2.replace('.', ''));

    let dif, base;
    if (f1_base > f2_base) {
        dif = f1_base / f2_base;
        base = f1_base;
        f2 = f2 * dif;
    } else {
        dif = f2_base / f1_base;
        base = f2_base;
        f1 = f1 * dif;
    }

    return (f1 * f2) / base;
};

console.log(0.1 * 0.2);
console.log(toAlgebraic("0.1", "0.2"));

您可能需要重构此代码,因为我不擅长编程:)

使用编号(1.234443)。至固定(2);它将打印1.23

function test(){
    var x = 0.1 * 0.2;
    document.write(Number(x).toFixed(2));
}
test();