我有以下虚拟测试脚本:
函数测试(){变量x=0.1*0.2;document.write(x);}测试();
这将打印结果0.020000000000000004,而它应该只打印0.02(如果您使用计算器)。据我所知,这是由于浮点乘法精度的错误。
有没有人有一个好的解决方案,在这种情况下,我得到了正确的结果0.02?我知道还有一些函数,比如toFixed或舍入,这是另一种可能,但我真的希望在不进行任何切割和舍入的情况下打印整个数字。我只是想知道你们中的一个人是否有一些好的、优雅的解决方案。
当然,否则我会舍入到10位数左右。
避免在使用整数的操作过程中处理浮点
正如迄今为止投票最多的答案所述,你可以使用整数,这意味着你所使用的每一个小数乘以10,然后将结果除以所使用的相同数字。
例如,如果使用2个小数,则在执行运算之前,将所有因子乘以100,然后将结果除以100。
下面是一个示例,Result1是通常的结果,Result2使用解决方案:
var Factor1=“1110.7”;var Factor2=“2220.2”;var Result1=数字(因子1)+数字(因子2);var Result2=((数量(因子1)*100)+(数量(系数2)*100))/100;var Result3=(Number(parseFloat(Number(Factor1))+parseFlat(Number(Factor2))).toPecision(2));document.write(“Result1:”+Result1+“<br>Result2:”+Result2+“<br>Result3:”+Result3);
第三个结果是显示改用parseFloat时发生的情况,这在我们的案例中产生了冲突。
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;以有效数字表示的精度;始终应用精度;随机数。
链接到详细比较
我找不到使用内置的Number.EPSILON来解决这类问题的解决方案,因此我的解决方案如下:
function round(value, precision) {
const power = Math.pow(10, precision)
return Math.round((value*power)+(Number.EPSILON*power)) / power
}
这使用1和大于1的最小浮点数之间的已知最小差值来修正EPSILON舍入误差,结果仅比舍入阈值低一个EPSILON。
64位浮点的最大精度为15,32位浮点的最高精度为6。您的javascript可能是64位。