我有以下虚拟测试脚本:

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

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

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

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


当前回答

当添加两个浮点值时,它永远不会给出精确的值,因此我们需要将其固定为有助于我们进行比较的某个数字。

console.log((parseFloat(0.1)+parseFlat(0.2)).toFixed(1)==parseFloat(0.3).toFixed(1));

其他回答

这对我有用:

function round_up( value, precision ) { 
    var pow = Math.pow ( 10, precision ); 
    return ( Math.ceil ( pow * value ) + Math.ceil ( pow * value - Math.ceil ( pow * value ) ) ) / pow; 
}

round_up(341.536, 2); // 341.54

注意,对于一般用途,这种行为可能是可以接受的。当比较这些浮点值以确定适当的操作时,会出现问题。随着ES6的出现,定义了一个新的常数Number.EPSILON来确定可接受的误差容限:所以不要像这样进行比较

0.1 + 0.2 === 0.3 // which returns false

您可以定义自定义比较函数,如下所示:

function epsEqu(x, y) {
    return Math.abs(x - y) < Number.EPSILON;
}
console.log(epsEqu(0.1+0.2, 0.3)); // true

资料来源:http://2ality.com/2015/04/numbers-math-es6.html#numberepsilon

试试我的千年算术库,你可以在这里看到。如果你想要更高版本,我可以给你买一个。

为了避免这种情况,您应该使用整数值而不是浮点。因此,当您希望使用值*100进行2个位置的精度工作时,对于3个位置使用1000。显示时,使用格式化程序放入分隔符。

许多系统省略了以这种方式处理小数。这就是为什么许多系统使用美分(作为整数)而不是美元/欧元(作为浮点)的原因。

phpjs.org中的round()函数工作得很好:http://phpjs.org/functions/round

num = .01 + .06;  // yields 0.0699999999999
rnum = round(num,12); // yields 0.07