详解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
三.小总结
上面自己自己暂时知道的一些解决方案.不太清楚是否有开源的更可靠的三方库来解决这个问题。以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。