javascript避免數(shù)字計算精度誤差的方法詳解
如果我問你 0.1 + 0.2 等于幾?你可能會送我一個白眼,0.1 + 0.2 = 0.3 啊,那還用問嗎?但是你知道嗎,同樣的問題放在編程語言中,或許就不是想象中那么簡單的事兒了。
不信?我們先來看一段 JS。
var numA = 0.1;
var numB = 0.2;
alert( (numA + numB) === 0.3 );
執(zhí)行結(jié)果是 false。沒錯,當我第一次看到這段代碼時,我也理所當然地以為它是 true,但是執(zhí)行結(jié)果讓我大跌眼鏡,是我的打開方式不對嗎?非也非也。我們再執(zhí)行以下代碼試試就知道結(jié)果為什么是 false 了。
var numA = 0.1;
var numB = 0.2;
alert( numA + numB );
原來,0.1 + 0.2 = 0.30000000000000004。是不是很奇葩?其實對于浮點數(shù)的四則運算,幾乎所有的編程語言都會有類似精度誤差的問題,只不過在 C++/C#/Java 這些語言中已經(jīng)封裝好了方法來避免精度的問題,而 JavaScript 是一門弱類型的語言,從設(shè)計思想上就沒有對浮點數(shù)有個嚴格的數(shù)據(jù)類型,所以精度誤差的問題就顯得格外突出。下面就分析下為什么會有這個精度誤差,以及怎樣修復這個誤差。
首先,我們要站在計算機的角度思考 0.1 + 0.2 這個看似小兒科的問題。我們知道,能被計算機讀懂的是二進制,而不是十進制,所以我們先把 0.1 和 0.2 轉(zhuǎn)換成二進制看看:
0.1 => 0.0001 1001 1001 1001…(無限循環(huán))
0.2 => 0.0011 0011 0011 0011…(無限循環(huán))
雙精度浮點數(shù)的小數(shù)部分最多支持 52 位,所以兩者相加之后得到這么一串 0.0100110011001100110011001100110011001100110011001100 因浮點數(shù)小數(shù)位的限制而截斷的二進制數(shù)字,這時候,我們再把它轉(zhuǎn)換為十進制,就成了 0.30000000000000004。
原來如此,那怎么解決這個問題呢?我想要的結(jié)果就是 0.1 + 0.2 === 0.3 ?。。。?/p>
有種最簡單的解決方案,就是給出明確的精度要求,在返回值的過程中,計算機會自動四舍五入,比如:
var numA = 0.1;
var numB = 0.2;
alert( parseFloat((numA + numB).toFixed(2)) === 0.3 );
但是明顯這不是一勞永逸的方法,如果有一個方法能幫我們解決這些浮點數(shù)的精度問題,那該多好。我們來試試下面這個方法:
Math.formatFloat = function(f, digit) {
var m = Math.pow(10, digit);
return parseInt(f * m, 10) / m;
}
var numA = 0.1;
var numB = 0.2;
alert(Math.formatFloat(numA + numB, 1) === 0.3);
這個方法是什么意思呢?為了避免產(chǎn)生精度差異,我們要把需要計算的數(shù)字乘以 10 的 n 次冪,換算成計算機能夠精確識別的整數(shù),然后再除以 10 的 n 次冪,大部分編程語言都是這樣處理精度差異的,我們就借用過來處理一下 JS 中的浮點數(shù)精度誤差。
如果下次再有人問你 0.1 + 0.2 等于幾,你可要小心回答咯??!
相關(guān)文章
LayUi使用switch開關(guān),動態(tài)的去控制它是否被啟用的方法
今天小編就為大家分享一篇LayUi使用switch開關(guān),動態(tài)的去控制它是否被啟用的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09JavaScript Event學習補遺 addEventSimple
這里有個addEventSimple和removeEventSimple函數(shù),有時候需要不那么顯眼的事件處理程序的時候我就用這兩個函數(shù)注冊。2010-02-02JavaScript+html5 canvas制作的圓中圓效果實例
這篇文章主要介紹了JavaScript+html5 canvas制作的圓中圓效果,結(jié)合完整實例形式分析了基于JavaScript與html5 canvas技術(shù)實現(xiàn)的圖形繪制與顏色隨機填充技巧,需要的朋友可以參考下2016-01-01JavaScript必知必會(二) null 和undefined
這篇文章主要介紹了JavaScript必知必會(二) null 和undefined的相關(guān)資料,非常不錯具有參考借鑒價值,需要的朋友可以參考下2016-06-06webpack4.0+vue2.0利用批處理生成前端單頁或多頁應(yīng)用的方法
這篇文章主要介紹了webpack4.0+vue2.0利用批處理生成前端單頁或多頁應(yīng)用的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-06-06javascript字符串對象常用api函數(shù)小結(jié)(連接,替換,分割,轉(zhuǎn)換等)
這篇文章主要介紹了javascript字符串對象常用api函數(shù),結(jié)合實例形式總結(jié)分析了javascript常用的連接、替換、分割、轉(zhuǎn)換等相關(guān)函數(shù)與使用方法,需要的朋友可以參考下2016-09-09