js 浮點數(shù)計算

在做項目的時候疟呐,涉及到金額加減時脆栋,經(jīng)常會出現(xiàn)計算精度的問題打却,常見例子如下:

     加法        

          0.1 + 0.2 = 0.30000000000000004

          0.7 + 0.1 = 0.7999999999999999

          0.2 + 0.4 = 0.6000000000000001

     減法

          1.5 - 1.2 = 0.30000000000000004

           0.3 - 0.2 = 0.09999999999999998

     乘法

           0.8 * 3 = 2.4000000000000004

           35.41 * 100 = 3540.9999999999995

      除法

           0.3 / 0.1 = 2.9999999999999996

           0.69 / 10 = 0.06899999999999999

在遇到浮點數(shù)運算后出現(xiàn)的精度問題時,起初想等加完之后使用toFixed(2)來解決的叛甫,toFixed()方法可把Number四舍五入為指定小數(shù)位數(shù)的數(shù)字

測試發(fā)現(xiàn)還是存在一定誤差

為什么會產(chǎn)生

JavaScript中所有數(shù)字包括整數(shù)和小數(shù)都只有一種類型 — Number。它的實現(xiàn)遵循 IEEE 754 標(biāo)準杨伙,使用64位固定長度來表示其监,也就是標(biāo)準的 double 雙精度浮點數(shù),

這樣的存儲結(jié)構(gòu)優(yōu)點是可以歸一化處理整數(shù)和小數(shù)限匣,節(jié)省存儲空間抖苦。

64位比特又可分為三個部分:

符號位S:第 1 位是正負數(shù)符號位(sign),0代表正數(shù)米死,1代表負數(shù)

指數(shù)位E:中間的 11 位存儲指數(shù)(exponent)锌历,用來表示次方數(shù)

尾數(shù)位M:最后的 52 位是尾數(shù)(mantissa),超出的部分自動進一舍零

然后當(dāng)javaScript運算時峦筒,會先把十進制的0.1和0.2會被轉(zhuǎn)換成二進制的究西,但是由于浮點數(shù)用二進制表示時是無窮的:

   0.1 -> 0.0001 1001 1001 1001...(1100循環(huán))

   0.2 -> 0.0011 0011 0011 0011...(0011循環(huán))

IEEE 754 標(biāo)準的 64 位雙精度浮點數(shù)的小數(shù)部分最多支持53位二進制位,所以兩者相加之后得到二進制為:

   0.0100110011001100110011001100110011001100110011001100

因浮點數(shù)小數(shù)位的限制而截斷的二進制數(shù)字物喷,再轉(zhuǎn)換為十進制卤材,就成了0.30000000000000004。所以在進行算術(shù)計算時會產(chǎn)生誤差峦失。

如何解決

大概思路就是把浮點數(shù)轉(zhuǎn)化成整數(shù)(乘以10的n次冪)去加減扇丛,然后在降級處理(除以10的n次冪)

例如: 0.1 + 0.2 == 0.3 //false

       (0.1*10 + 0.2*10)/10 == 0.3 //true

本以為這樣就能完美解決了,尷尬的事情出行了

 18.4 * 100 = 1839.9999999998 

所以最終決定把數(shù)值先toString之后通過split方法切割小數(shù)點尉辑,把小數(shù)點位數(shù)補成兩位后帆精,通過字符串拼接的方式拼接起來然后轉(zhuǎn)成數(shù)值進行加減,最后在除以100即可隧魄。

代碼如下:

//補全位數(shù)
function operation(num) {
//如果是整數(shù)的話默認補兩位小數(shù)
if (num) {
num = num.slice(0,2);
return num.length === 1 ? num = num + '0' : num;
} else {
return '00'
}
}
//處理浮點數(shù)想加
var addNUm = function (num1,num2) {

  var array1 = num1.toString().split("."),//轉(zhuǎn)化成字符串并已小數(shù)點切割 
  array2 = num2.toString().split(".");
  //如果是整數(shù)的話默認補兩位小數(shù)
  array1[1] = operation(array1[1]);
  array2[1] = operation(array2[1]);
  //把整數(shù)部分和小數(shù)部分拼接起來然后在轉(zhuǎn)成數(shù)字類型
  var num1 = Number(array1[0] + array1[1]),
  num2 = Number(array2[0] + array2[1]);
  //整數(shù)想加之后除以100
 return (num1 + num2) / 100;

}

addNUm(0.1,0.2);

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卓练,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子购啄,更是在濱河造成了極大的恐慌襟企,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闸溃,死亡現(xiàn)場離奇詭異整吆,居然都是意外死亡拱撵,警方通過查閱死者的電腦和手機辉川,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拴测,“玉大人乓旗,你說我怎么就攤上這事〖鳎” “怎么了屿愚?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵汇跨,是天一觀的道長。 經(jīng)常有香客問我妆距,道長穷遂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任娱据,我火速辦了婚禮蚪黑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘中剩。我一直安慰自己忌穿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布结啼。 她就那樣靜靜地躺著掠剑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪郊愧。 梳的紋絲不亂的頭發(fā)上朴译,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音糕珊,去河邊找鬼动分。 笑死,一個胖子當(dāng)著我的面吹牛红选,可吹牛的內(nèi)容都是我干的澜公。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼喇肋,長吁一口氣:“原來是場噩夢啊……” “哼坟乾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蝶防,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤甚侣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后间学,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殷费,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年低葫,在試婚紗的時候發(fā)現(xiàn)自己被綠了详羡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡嘿悬,死狀恐怖实柠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情善涨,我是刑警寧澤窒盐,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布草则,位于F島的核電站,受9級特大地震影響蟹漓,放射性物質(zhì)發(fā)生泄漏炕横。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一葡粒、第九天 我趴在偏房一處隱蔽的房頂上張望看锉。 院中可真熱鬧,春花似錦塔鳍、人聲如沸伯铣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腔寡。三九已至,卻和暖如春掌唾,著一層夾襖步出監(jiān)牢的瞬間放前,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工糯彬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凭语,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓撩扒,卻偏偏與公主長得像似扔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子搓谆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容