我有以下虚拟测试脚本:

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

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

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

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


当前回答

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

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

其他回答

您不能用二进制浮点类型(这是ECMAScript用来表示浮点值的)精确地表示大多数小数。因此,除非您使用任意精度的算术类型或基于小数的浮点类型,否则没有一个优雅的解决方案。例如,Windows附带的计算器应用程序现在使用任意精度算法来解决这个问题。

从浮点指南:

我可以做什么来避免这个问题?这取决于什么样的你正在做的计算。如果你真的需要你的结果精确相加,特别是当你使用货币:使用特殊小数数据类型。如果你只是不想看到所有多余的小数点:将结果四舍五入设置为固定格式小数位数显示它。如果没有可用的十进制数据类型,另一种方法是工作使用整数,例如,do money完全以美分计算。但是这是更多的工作,有一些缺点。

注意,第一点仅适用于您确实需要特定的精确小数行为的情况。大多数人不需要这样做,他们只是对自己的程序无法正确处理1/10这样的数字感到愤怒,而没有意识到如果出现1/3这样的错误,他们甚至不会眨眼。

如果第一点确实适用于您,请使用BigDecimal for JavaScript或DecimalJS,这实际上解决了问题,而不是提供不完美的解决方法。

decimal.js、big.js或bignumber.js可用于避免Javascript中的浮点操作问题:

0.1 * 0.2                                // 0.020000000000000004
x = new Decimal(0.1)
y = x.times(0.2)                          // '0.2'
x.times(0.2).equals(0.2)                  // true

big.js:极简主义;易于使用;以小数位数表示的精度;精度仅适用于除法。

bignumber.js:基数2-64;配置选项;NaN;无穷以小数位数表示的精度;精度仅适用于除法;基本前缀。

decimal.js:基数2-64;配置选项;NaN;无穷非整数幂,exp,ln,log;以有效数字表示的精度;始终应用精度;随机数。

链接到详细比较

您正在寻找JavaScript的sprintf实现,这样您就可以以期望的格式写出带有小错误的浮点数(因为它们是以二进制格式存储的)。

试试javascript sprintf,你可以这样称呼它:

var yourString = sprintf("%.2f", yourNumber);

将数字打印为带有两个小数点的浮点数。

如果您不希望仅为浮点舍入到给定精度而包含更多文件,也可以使用Number.toFixed()进行显示。

我的回答可能会迟到,但我的解决方案是:

函数浮点(方程式,精度=9){return Math.floor(公式*(10**精度))/(10**精确度);}console.log(浮点(0.1*0.2));//=>0.02console.log(浮点(0.2+0.4));//=>0.6console.log(浮点(1/3));//=>0.333333333console.log(浮点(1/3,2));//=>0.33