js精準(zhǔn)計(jì)算
var numA = 0.1; var numB = 0.2; alert( numA + numB );
0.1 + 0.2 = 0.30000000000000004。計(jì)算精度誤差問(wèn)題(和二進(jìn)制相關(guān))。
對(duì)于浮點(diǎn)數(shù)的四則運(yùn)算,幾乎所有的編程語(yǔ)言都會(huì)有類(lèi)似精度誤差的問(wèn)題,只不過(guò)在 C++/C#/Java 這些語(yǔ)言中已經(jīng)封裝好了方法來(lái)避免精度的問(wèn)題,而JavaScript是一門(mén)弱類(lèi)型的語(yǔ)言,從設(shè)計(jì)思想上就沒(méi)有對(duì)浮點(diǎn)數(shù)有個(gè)嚴(yán)格的數(shù)據(jù)類(lèi)型,所以精度誤差的問(wèn)題就顯得格外突出。
我們先把 0.1 和 0.2 轉(zhuǎn)換成二進(jìn)制看看:
0.1 => 0.0001 1001 1001 1001…(無(wú)限循環(huán))
0.2 => 0.0011 0011 0011 0011…(無(wú)限循環(huán))
雙精度浮點(diǎn)數(shù)的小數(shù)部分最多支持 52 位,所以?xún)烧呦嗉又蟮玫竭@么一串 0.0100110011001100110011001100110011001100110011001100 因浮點(diǎn)數(shù)小數(shù)位的限制而截?cái)嗟亩M(jìn)制數(shù)字,這時(shí)候,我們?cè)侔阉D(zhuǎn)換為十進(jìn)制,就成了 0.30000000000000004。
如何解決呢?
首先將數(shù)乘以10的冪次方去掉小數(shù)位得到可以轉(zhuǎn)化二進(jìn)制的整數(shù),計(jì)算之后再還原。
/** ** 除法函數(shù),用來(lái)得到精確的除法結(jié)果 ** 說(shuō)明:JavaScript的除法結(jié)果會(huì)有誤差,在兩個(gè)浮點(diǎn)數(shù)相除的時(shí)候會(huì)比較明顯。這個(gè)函數(shù)返回較為精確的除法結(jié)果。 ** 調(diào)用:accdiv(arg1,arg2) ** 返回值:arg1除以arg2的精確結(jié)果 **/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) * Math.pow(10, t2 - t1); }}/** ** 加法函數(shù),用來(lái)得到精確的加法結(jié)果 ** 說(shuō)明:javascript的加法結(jié)果會(huì)有誤差,在兩個(gè)浮點(diǎn)數(shù)相加的時(shí)候會(huì)比較明顯。這個(gè)函數(shù)返回較為精確的加法結(jié)果。 ** 調(diào)用:accAdd(arg1,arg2) ** 返回值:arg1加上arg2的精確結(jié)果 **/function accAdd(arg1, arg2) { var r1, r2, m, c; try {r1 = arg1.toString().split('.')[1].length; } catch (e) {r1 = 0; } try {r2 = arg2.toString().split('.')[1].length; } catch (e) {r2 = 0; } c = Math.abs(r1 - r2); m = Math.pow(10, Math.max(r1, r2)); if (c > 0) {var cm = Math.pow(10, c);if (r1 > r2) { arg1 = Number(arg1.toString().replace('.', '')); arg2 = Number(arg2.toString().replace('.', '')) * cm;} else { arg1 = Number(arg1.toString().replace('.', '')) * cm; arg2 = Number(arg2.toString().replace('.', ''));} } else {arg1 = Number(arg1.toString().replace('.', ''));arg2 = Number(arg2.toString().replace('.', '')); } return (arg1 + arg2) / m;}/** ** 乘法函數(shù),用來(lái)得到精確的乘法結(jié)果 ** 說(shuō)明:javascript的乘法結(jié)果會(huì)有誤差,在兩個(gè)浮點(diǎn)數(shù)相乘的時(shí)候會(huì)比較明顯。這個(gè)函數(shù)返回較為精確的乘法結(jié)果。 ** 調(diào)用:accMul(arg1,arg2) ** 返回值:arg1乘以 arg2的精確結(jié)果 **/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);}
以上就是js精準(zhǔn)計(jì)算的詳細(xì)內(nèi)容,更多關(guān)于js精準(zhǔn)計(jì)算的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. python用pyecharts實(shí)現(xiàn)地圖數(shù)據(jù)可視化2. python+requests+pytest接口自動(dòng)化的實(shí)現(xiàn)示例3. 使用Spry輕松將XML數(shù)據(jù)顯示到HTML頁(yè)的方法4. 詳解Python 3.10 中的新功能和變化5. npm下載慢或下載失敗問(wèn)題解決的三種方法6. ASP編碼必備的8條原則7. Python中re模塊的常用方法總結(jié)8. python基于opencv批量生成驗(yàn)證碼的示例9. ASP錯(cuò)誤捕獲的幾種常規(guī)處理方式10. 如何用python開(kāi)發(fā)Zeroc Ice應(yīng)用
