我有以下虚拟测试脚本:

函数测试(){变量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时发生的情况,这在我们的案例中产生了冲突。

其他回答

我喜欢佩德罗·拉达里亚的解决方案,并使用类似的方法。

function strip(number) {
    return (parseFloat(number).toPrecision(12));
}

与Pedros解决方案不同,这将向上取整0.999……重复,并精确到最低有效位数的正负一。

注意:当处理32位或64位浮点时,应该使用toPrecision(7)和toPrecision(15)以获得最佳结果。有关原因的信息,请参阅此问题。

这对我有用:

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

浮点值编程缺乏精度

在不同的编程语言中,浮点值编程缺乏精度是一个已知的问题。Javascript是使用浮点值进行数学运算时遇到问题的一种。这种问题主要是由于这些编程语言实现的浮点数的内存二进制表示。

让我们希望编程语言、编译器、硬件开发人员和工程师能够一次性解决这些问题,至少解决1024个浮点数字。。。也许这将足以让99.999%的其他开发人员在下一个世纪的编程中感到安心。。。

一种可能的解决方案:转换为整数,计算,然后返回

一种可能的解决方案是将浮点数转换为整数,执行计算,然后将结果转换回浮点数。这似乎在大多数时候都有效。原则上:

函数测试(){变量x=0.1*0.2;//原始方法变量y=((0.1*10)*(0.2*10))/100;//可行的解决方案document.write(x+'<br>'+y);}测试();

当然,在需要的情况下,可以相应地调整功能,例如:

函数测试(){变量x=0.12*0.23;//原始方法变量y=((0.12*100)*(0.23*100))/10000;//可行的解决方案document.write(x+'<br>'+y);}测试();

它也可以是自动化的:

函数myToInt(v){设i=1;设r;而(r%1!=0){i=i*10;r=v*i;}返回[r,i];}函数测试(){设x=0.11111111;设y=0.22222222;设a=x*y;//原始方法[x,i]=myToInt(x);[y,j]=myToInt(y);设d=i*j;设b=x*y/d;//另一种可行的解决方案console.log(a+'\n'+b)document.write(a+'<br>'+b);}测试();

考虑到这一点,我们可以这样做:

函数myToInt(v){设i=1;设r;而(r%1!=0){i=i*10;r=v*i;}返回[r,i];}函数测试(){设x=14898设y=10.8设z=100设a=x*y/z;//原始方法[y,i]=myToInt(y);设b=(x*y)/(z*i);//另一种可行的解决方案console.log(a+'\n'+b)document.write(a+'<br>'+b);}测试();

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

看看固定点算法。如果你想操作的数字范围很小(例如货币),它可能会解决你的问题。我会将其舍入为几个十进制值,这是最简单的解决方案。