详解JS-- 浮点数运算处理
一.问题描述
最近在做一个项目,页面上会存在一些JS浮点数的运算,发现JS浮点数运算存在一些bug.譬如:
0.1+0.2==0.30000000000000004 0.1+0.7==0.7999999999999999 7*0.8==5.6000000000000005 5.6/7==0.7999999999999999
二.解决方案
JS运算后都会有很小的误差.不像.Net或者Java那样准确.主要是JS重点不在运算上面,可是有时候项目一定要用到.想了一下大概有两种解决方案
A方案一:
运算结果保留2-3位小数位数.前端界面一般用到的运算比较少。精度要求不会太高。所以取2位小数位即可。
B.方案二:
将小数位数转换为整数运算.譬如:
0.1+0.2=》(1+2)/10==0.3 0.1+0.7=》(1+7)/10==0.8 7*0.8==(7*8)/10==5.6 5.6/7==(56/7)/10==0.1
为了方便调用.所以我们可以提取一个公共的方法出来.譬如下面的JSMath库,JSMath重写了加减乘除.会先将参数转换为整数再运算JSMath(参数1).操作(参数2)
参数1和参数2分别就是运算的第一个Number和第二个Number.计算后通过Value属性获取值.
(function(){ varJSMath=function(){ returnthis; } JSMath.prototype.from=function(value){ //支持JSMath参数传递主要是用于嵌套的调用 if((typeof(value)=='object')&&(value.value!=undefined)){ this.value=value.value; }else{ this.value=value; } returnthis; } //加法 JSMath.prototype.add=function(value){ varthisValueString=this.value.toString(); varvalueString=value.toString(); vartimesCount1=0; vartimesCount2=0; if(thisValueString.indexOf('.')>0){ timesCount1=thisValueString.split('.')[1].length; } if(valueString.indexOf('.')>0){ timesCount2=valueString.split('.')[1].length; } varmaxtimeCount=timesCount1>timesCount2?timesCount1:timesCount2; this.value=(Math.pow(10,maxtimeCount)*this.value+Math.pow(10,maxtimeCount)*value)/Math.pow(10,maxtimeCount); returnthis; } //减法 JSMath.prototype.sub=function(value){ varthisValueString=this.value.toString(); varvalueString=value.toString(); vartimesCount1=0; vartimesCount2=0; if(thisValueString.indexOf('.')>0){ timesCount1=thisValueString.split('.')[1].length; } if(valueString.indexOf('.')>0){ timesCount2=valueString.split('.')[1].length; } varmaxtimeCount=timesCount1>timesCount2?timesCount1:timesCount2; this.value=(Math.pow(10,maxtimeCount)*this.value-Math.pow(10,maxtimeCount)*value)/Math.pow(10,maxtimeCount); returnthis; } //除法 JSMath.prototype.div=function(value){ varthisValueString=this.value.toString(); varvalueString=value.toString(); vartimesCount1=0; vartimesCount2=0; if(thisValueString.indexOf('.')>0){ timesCount1=thisValueString.split('.')[1].length; } if(valueString.indexOf('.')>0){ timesCount2=valueString.split('.')[1].length; } varmaxtimeCount=timesCount1>timesCount2?timesCount1:timesCount2; this.value=((Math.pow(10,maxtimeCount)*this.value)/(Math.pow(10,maxtimeCount)*value)); returnthis; } //乘法 JSMath.prototype.times=function(value){ varthisValueString=this.value.toString(); varvalueString=value.toString(); vartimesCount1=0; vartimesCount2=0; if(thisValueString.indexOf('.')>0){ timesCount1=thisValueString.split('.')[1].length; } if(valueString.indexOf('.')>0){ timesCount2=valueString.split('.')[1].length; } varmaxtimeCount=timesCount1>timesCount2?timesCount1:timesCount2; this.value=(Math.pow(10,maxtimeCount)*this.value*Math.pow(10,maxtimeCount)*value)/Math.pow(10,maxtimeCount*2); returnthis; } if(window.JSMath==undefined){ window.JSMath=function(value){ varresult=newJSMath(); result.from(value); returnresult; } } })()
B1.基本运算
0.1+0.2 =>JSMath(0.1).add(0.2).value==0.3 7+0.8 =>JSMath(7).times(0.8).value==5.6 5.6/7 =>JSMath(5.6).div(7).value=0.8
B2.多目运算
0.05+0.05+0.2 =>JSMath(JSMath(0.05).add(0.05)).add(0.2).value==0.3 (5+0.6)/7 =>JSMath(JSMath(5).add(0.6)).div(7).value==0.8
三.小总结
上面自己自己暂时知道的一些解决方案.不太清楚是否有开源的更可靠的三方库来解决这个问题。以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。