天天看點

解決JS浮點數運算出現Bug的方法

解決JS浮點數運算出現Bug的方法

解決JS浮點數運算出現Bug的方法,需要的朋友可以參考一下

id="cproIframe_u1892994_2" width="580" height="90" src="http://pos.baidu.com/acom?adn=3&at=231&aurl=&cad=1&ccd=32&cec=GBK&cfv=11&ch=0&col=zh-CN&conBW=0&conOP=1&cpa=1&dai=2&dis=0&ltr=http%3A%2F%2Fwww.jb51.net%2Farticle%2F45136.htm&ltu=http%3A%2F%2Fwww.jb51.net%2Farticle%2F34705.htm&lu_161=0&lunum=6&n=jb51_cpr&pcs=1349x614&pis=10000x10000&ps=491x209&psr=1366x768&pss=1349x492&qn=1a7a8b18e9293ba2&rad=&rsi0=580&rsi1=90&rsi5=4&rss0=%23FFFFFF&rss1=%23F7FCFF&rss2=%230000ff&rss3=%23444444&rss4=%23008000&rss5=&rss6=%23e10900&rss7=&scale=&skin=tabcloud_skin_3&stid=5&td_id=1892994&titFF=%E5%AE%8B%E4%BD%93&titFS=12&titTA=left&tn=text_default_580_90&tpr=1423398314899&ts=1&version=2.0&xuanting=0&dtm=BAIDU_DUP2_SETJSONADSLOT&dc=2&di=u1892994&tt=1423398314884.110.218.218" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true">

37.5*5.5=206.08 (JS算出來是這樣的一個結果,我四舍五入取兩位小數) 

我先懷疑是四舍五入的問題,就直接用JS算了一個結果為:206.08499999999998 

怎麼會這樣,兩個隻有一位小數的數字相乘,怎麼可能多出這麼小數點出來。 

我Google了一下,發現原來這是JavaScript浮點運算的一個bug。 

比如:7*0.8 JavaScript算出來就是:5.6000000000000005

網上找到了一些解決辦法,就是重新寫了一些浮點運算的函數或直接擴大倍數運算。 

下面就把這些方法摘錄下來,以供遇到同樣問題的朋友參考:

複制代碼代碼如下:

//除法函數,用來得到精确的除法結果 
  
 //說明:javascript的除法結果會有誤差,在兩個浮點數相除的時候會比較明顯。這個函數傳回較為精确的除法結果。 
  
 //調用:accDiv(arg1,arg2) 
  
 //傳回值:arg1除以arg2的精确結果 
   
 function accDiv(arg1,arg2){ 
 var t1=0,t2=0,r1,r2; 
 try{t1=arg1.toString().split(".")[1].length}catch(e){} 
 try{t2=arg2.toString().split(".")[1].length}catch(e){} 
 with(Math){ 
 r1=Number(arg1.toString().replace(".","")) 
 r2=Number(arg2.toString().replace(".","")) 
 return (r1/r2)*pow(10,t2-t1); 
 } 
 } 
 //給Number類型增加一個div方法,調用起來更加友善。 
 Number.prototype.div = function (arg){ 
 return accDiv(this, arg); 
 } //乘法函數,用來得到精确的乘法結果 
 //說明:javascript的乘法結果會有誤差,在兩個浮點數相乘的時候會比較明顯。這個函數傳回較為精确的乘法結果。 
 //調用:accMul(arg1,arg2) 
 //傳回值:arg1乘以arg2的精确結果 
 function accMul(arg1,arg2) 
 { 
 var m=0,s1=arg1.toString(),s2=arg2.toString(); 
 try{m+=s1.split(".")[1].length}catch(e){} 
 try{m+=s2.split(".")[1].length}catch(e){} 
 return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m) 
 } 
 //給Number類型增加一個mul方法,調用起來更加友善。 
 Number.prototype.mul = function (arg){ 
 return accMul(arg, this); 
 } //加法函數,用來得到精确的加法結果 
 //說明:javascript的加法結果會有誤差,在兩個浮點數相加的時候會比較明顯。這個函數傳回較為精确的加法結果。 
 //調用:accAdd(arg1,arg2) 
 //傳回值:arg1加上arg2的精确結果 
 function accAdd(arg1,arg2){ 
 var r1,r2,m; 
 try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 
 try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 
 m=Math.pow(10,Math.max(r1,r2)) 
 return (arg1*m+arg2*m)/m 
 } 
 //給Number類型增加一個add方法,調用起來更加友善。 
 Number.prototype.add = function (arg){ 
 return accAdd(arg,this); 
 } //減法函數,用來得到精确的減法結果 
 //說明:javascript的減法結果會有誤差,在兩個浮點數相加的時候會比較明顯。這個函數傳回較為精确的減法結果。 
 //調用:accSubtr(arg1,arg2) 
 //傳回值:arg1減去arg2的精确結果 
 function accSubtr(arg1,arg2){
 var r1,r2,m,n;
 try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
 try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
 m=Math.pow(10,Math.max(r1,r2));
 //動态控制精度長度
 n=(r1>=r2)?r1:r2;
 return ((arg1*m-arg2*m)/m).toFixed(n);
 } 
 //給Number類型增加一個subtr 方法,調用起來更加友善。 
 Number.prototype.subtr = function (arg){ 
 return accSubtr(arg,this); 
 }      

在你要用的地方包含這些函數,然後調用它來計算就可以了。

/如果在知道小數位個數的前提下,可以考慮通過将浮點數放大倍數到整型(最後再除以相應倍數),再進行運算操作,這樣就能得到正确的結果了

<script> 
  
 alert(11*(22.9*10)/10);
  
 </script>      

繼續閱讀