JavaScript 浮點數(shù)運算 精度問題
更新時間:2009年10月06日 00:15:53 作者:
JavaScript小數(shù)在做四則運算時,精度會丟失,這會在項目中引起諸多不便,先請看下面腳本。
Js代碼
<script type="text/javascript" language="javascript">
alert(1/3);//彈出: 0.3333333333333333
alert(0.09999999 + 0.00000001);//彈出: 0.09999999999999999
alert(-0.09999999 - 0.00000001);//彈出: -0.09999999999999999
alert(0.012345 * 0.000001);//彈出: 1.2344999999999999e-8
alert(0.000001 / 0.0001);//彈出: 0.009999999999999998
</script>
<script type="text/javascript" language="javascript">
alert(1/3);//彈出: 0.3333333333333333
alert(0.09999999 + 0.00000001);//彈出: 0.09999999999999999
alert(-0.09999999 - 0.00000001);//彈出: -0.09999999999999999
alert(0.012345 * 0.000001);//彈出: 1.2344999999999999e-8
alert(0.000001 / 0.0001);//彈出: 0.009999999999999998
</script>
[code]
按正常計算的話,除第一行外(因為其本身就不能除盡),其他都應該要得到精確的結果,從彈出的結果我們卻發(fā)現(xiàn)不是我們想要的正確結果。為了解決浮點數(shù)運算不準確的問題,在運算前我們把參加運算的數(shù)先升級(10的X的次方)到整數(shù),等運算完后再降級(0.1的X的次方)?,F(xiàn)收集并整理貼于此,以備后用。
加法
Js代碼
[code]
//說明:javascript的加法結果會有誤差,在兩個浮點數(shù)相加的時候會比較明顯。這個函數(shù)返回較為精確的加法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.add = function (arg){
return accAdd(arg,this);
}
//說明:javascript的加法結果會有誤差,在兩個浮點數(shù)相加的時候會比較明顯。這個函數(shù)返回較為精確的加法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.add = function (arg){
return accAdd(arg,this);
}
減法
Js代碼
[code]
//說明:javascript的減法結果會有誤差,在兩個浮點數(shù)相加的時候會比較明顯。這個函數(shù)返回較為精確的減法結果。
//調(diào)用:accSub(arg1,arg2)
//返回值:arg1減上arg2的精確結果
function accSub(arg1,arg2){
return accAdd(arg1,-arg2);
}
//給Number類型增加一個sub方法,調(diào)用起來更加方便。
Number.prototype.sub = function (arg){
return accSub(this,arg);
}
//說明:javascript的減法結果會有誤差,在兩個浮點數(shù)相加的時候會比較明顯。這個函數(shù)返回較為精確的減法結果。
//調(diào)用:accSub(arg1,arg2)
//返回值:arg1減上arg2的精確結果
function accSub(arg1,arg2){
return accAdd(arg1,-arg2);
}
//給Number類型增加一個sub方法,調(diào)用起來更加方便。
Number.prototype.sub = function (arg){
return accSub(this,arg);
}
乘法
Js代碼
//說明:javascript的乘法結果會有誤差,在兩個浮點數(shù)相乘的時候會比較明顯。這個函數(shù)返回較為精確的乘法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.mul = function (arg){
return accMul(arg, this);
}
//說明:javascript的乘法結果會有誤差,在兩個浮點數(shù)相乘的時候會比較明顯。這個函數(shù)返回較為精確的乘法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.mul = function (arg){
return accMul(arg, this);
} 除法
Js代碼
//說明:javascript的除法結果會有誤差,在兩個浮點數(shù)相除的時候會比較明顯。這個函數(shù)返回較為精確的除法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.div = function (arg){
return accDiv(this, arg);
}
//說明:javascript的除法結果會有誤差,在兩個浮點數(shù)相除的時候會比較明顯。這個函數(shù)返回較為精確的除法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.div = function (arg){
return accDiv(this, arg);
}
測試一把
Js代碼
<script type="text/javascript" language="javascript">
/*
alert(0.09999999 + 0.00000001);//彈出: 0.09999999999999999
alert(-0.09999999 - 0.00000001);//彈出: -0.09999999999999999
alert(0.012345 * 0.000001);//彈出: 1.2344999999999999e-8
alert(0.000001 / 0.0001);//彈出: 0.009999999999999998
*/
alert(0.09999999.add(0.00000001));//彈出: 0.1
alert(-0.09999999.sub(0.00000001));//彈出: -0.09999998
alert(0.012345.mul(0.000001));//彈出: 1.2345e-8
alert(0.000001.div(0.0001));//彈出: 0.01
</script>
復制代碼 代碼如下:
<script type="text/javascript" language="javascript">
alert(1/3);//彈出: 0.3333333333333333
alert(0.09999999 + 0.00000001);//彈出: 0.09999999999999999
alert(-0.09999999 - 0.00000001);//彈出: -0.09999999999999999
alert(0.012345 * 0.000001);//彈出: 1.2344999999999999e-8
alert(0.000001 / 0.0001);//彈出: 0.009999999999999998
</script>
<script type="text/javascript" language="javascript">
alert(1/3);//彈出: 0.3333333333333333
alert(0.09999999 + 0.00000001);//彈出: 0.09999999999999999
alert(-0.09999999 - 0.00000001);//彈出: -0.09999999999999999
alert(0.012345 * 0.000001);//彈出: 1.2344999999999999e-8
alert(0.000001 / 0.0001);//彈出: 0.009999999999999998
</script>
[code]
按正常計算的話,除第一行外(因為其本身就不能除盡),其他都應該要得到精確的結果,從彈出的結果我們卻發(fā)現(xiàn)不是我們想要的正確結果。為了解決浮點數(shù)運算不準確的問題,在運算前我們把參加運算的數(shù)先升級(10的X的次方)到整數(shù),等運算完后再降級(0.1的X的次方)?,F(xiàn)收集并整理貼于此,以備后用。
加法
Js代碼
[code]
//說明:javascript的加法結果會有誤差,在兩個浮點數(shù)相加的時候會比較明顯。這個函數(shù)返回較為精確的加法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.add = function (arg){
return accAdd(arg,this);
}
//說明:javascript的加法結果會有誤差,在兩個浮點數(shù)相加的時候會比較明顯。這個函數(shù)返回較為精確的加法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.add = function (arg){
return accAdd(arg,this);
}
減法
Js代碼
[code]
//說明:javascript的減法結果會有誤差,在兩個浮點數(shù)相加的時候會比較明顯。這個函數(shù)返回較為精確的減法結果。
//調(diào)用:accSub(arg1,arg2)
//返回值:arg1減上arg2的精確結果
function accSub(arg1,arg2){
return accAdd(arg1,-arg2);
}
//給Number類型增加一個sub方法,調(diào)用起來更加方便。
Number.prototype.sub = function (arg){
return accSub(this,arg);
}
//說明:javascript的減法結果會有誤差,在兩個浮點數(shù)相加的時候會比較明顯。這個函數(shù)返回較為精確的減法結果。
//調(diào)用:accSub(arg1,arg2)
//返回值:arg1減上arg2的精確結果
function accSub(arg1,arg2){
return accAdd(arg1,-arg2);
}
//給Number類型增加一個sub方法,調(diào)用起來更加方便。
Number.prototype.sub = function (arg){
return accSub(this,arg);
}
乘法
Js代碼
復制代碼 代碼如下:
//說明:javascript的乘法結果會有誤差,在兩個浮點數(shù)相乘的時候會比較明顯。這個函數(shù)返回較為精確的乘法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.mul = function (arg){
return accMul(arg, this);
}
//說明:javascript的乘法結果會有誤差,在兩個浮點數(shù)相乘的時候會比較明顯。這個函數(shù)返回較為精確的乘法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.mul = function (arg){
return accMul(arg, this);
} 除法
Js代碼
//說明:javascript的除法結果會有誤差,在兩個浮點數(shù)相除的時候會比較明顯。這個函數(shù)返回較為精確的除法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.div = function (arg){
return accDiv(this, arg);
}
//說明:javascript的除法結果會有誤差,在兩個浮點數(shù)相除的時候會比較明顯。這個函數(shù)返回較為精確的除法結果。
//調(diào)用: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方法,調(diào)用起來更加方便。
Number.prototype.div = function (arg){
return accDiv(this, arg);
}
測試一把
Js代碼
復制代碼 代碼如下:
<script type="text/javascript" language="javascript">
/*
alert(0.09999999 + 0.00000001);//彈出: 0.09999999999999999
alert(-0.09999999 - 0.00000001);//彈出: -0.09999999999999999
alert(0.012345 * 0.000001);//彈出: 1.2344999999999999e-8
alert(0.000001 / 0.0001);//彈出: 0.009999999999999998
*/
alert(0.09999999.add(0.00000001));//彈出: 0.1
alert(-0.09999999.sub(0.00000001));//彈出: -0.09999998
alert(0.012345.mul(0.000001));//彈出: 1.2345e-8
alert(0.000001.div(0.0001));//彈出: 0.01
</script>
相關文章
javascript中Date對象應用之簡易日歷實現(xiàn)
這篇文章主要為大家詳細介紹了javascript中Date對象應用之簡易日歷實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-07-07bootstrap為水平排列的表單和內(nèi)聯(lián)表單設置可選的圖標
為水平排列的表單和內(nèi)聯(lián)表單設置可選的圖標。本文通過示例代碼給大家講解,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2017-02-02國外大牛IE版本檢測!現(xiàn)在IE都到9了,IE檢測代碼
有時會去看看國外大牛的一些代碼,并學習,引用,并感嘆大牛就是大牛,差距不是一點點,也在一點點的感嘆中慢慢拉進和大牛的距離2012-01-01document.all還是document.getElementsByName?
document.all還是document.getElementsByName?...2006-07-07Webpack-cli安裝成功后查看webpack -v報錯案例詳解
這篇文章主要介紹了Webpack-cli安裝成功后查看webpack -v報錯案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-09-0941個Web開發(fā)者必須收藏的JavaScript實用技巧
41個Web開發(fā)者必須收藏的JavaScript實用技巧,分享給大家,感興趣的小伙伴們可以參考一下2016-07-07不依賴Flash和任何JS庫實現(xiàn)文本復制與剪切附源碼下載
本篇文章給大家分享的文本復制與剪切板功能,實現(xiàn)此功能不依賴falsh插件和任何js庫實現(xiàn)的,感興趣的朋友一起看看吧2015-10-10