每天進(jìn)步一點(diǎn)點(diǎn)——js的浮點(diǎn)精度問題和科學(xué)計(jì)數(shù)法轉(zhuǎn)換

最近項(xiàng)目中用到了浮點(diǎn)的乘法運(yùn)算绩郎,遇到了兩個(gè)問題,一個(gè)是運(yùn)算的結(jié)果出現(xiàn)了誤差萍启,另一個(gè)問題是運(yùn)算結(jié)果出現(xiàn)了科學(xué)計(jì)數(shù)法总珠,需要將科學(xué)計(jì)數(shù)法轉(zhuǎn)換成普通數(shù)字。下面我們一一來處理勘纯。

1局服、js浮點(diǎn)數(shù)做數(shù)學(xué)運(yùn)算的時(shí)候出現(xiàn)誤差

我們都知道在計(jì)算機(jī)中所有的運(yùn)算都是以二進(jìn)制的形式進(jìn)行的,所以浮點(diǎn)數(shù)在進(jìn)行數(shù)學(xué)運(yùn)算的時(shí)候也會(huì)先轉(zhuǎn)換成二進(jìn)制驳遵,但是浮點(diǎn)數(shù)轉(zhuǎn)換成二進(jìn)制的時(shí)候可能會(huì)有無限位淫奔,而IEEE 754 標(biāo)準(zhǔn)的 64 位雙精度浮點(diǎn)數(shù)的小數(shù)部分最多支持 53 位二進(jìn)制位,所以二進(jìn)制表示的浮點(diǎn)數(shù)本身就有誤差堤结,數(shù)學(xué)運(yùn)算之后同樣存在誤差唆迁。
那么,怎樣消除這種誤差呢竞穷?目前通用的方式是:

//乘法
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);
}

原理就是將浮點(diǎn)數(shù)轉(zhuǎn)化正整數(shù)唐责,運(yùn)算之后再轉(zhuǎn)化成浮點(diǎn)數(shù)。下邊這邊文章有非常詳細(xì)的講解:JavaScript 浮點(diǎn)數(shù)運(yùn)算的精度問題瘾带。

2鼠哥、科學(xué)計(jì)數(shù)法轉(zhuǎn)換成普通數(shù)字

JavaScript在以下情景會(huì)自動(dòng)將數(shù)值轉(zhuǎn)換為科學(xué)計(jì)數(shù)法:
(1)小數(shù)點(diǎn)前的數(shù)字個(gè)數(shù)大于等于22位;
(2)小數(shù)點(diǎn)前邊是0看政,小數(shù)點(diǎn)后十分位(包含十分位)之后連續(xù)零的個(gè)數(shù)大于等于6個(gè)朴恳。
但是,我并不想以科學(xué)技術(shù)法的形式展示給用戶允蚣,于是找到了以下這個(gè)函數(shù)菜皂,并且做了逐行分析:

:function scientificToNumber(num) {
        if(/\d+\.?\d*e[\+\-]*\d+/i.test(num)) {    //正則匹配科學(xué)計(jì)數(shù)法的數(shù)字
          var zero = '0',                                    //
            parts = String(num).toLowerCase().split('e'), //拆分成系數(shù)和指數(shù)
            e = parts.pop(),//存儲(chǔ)指數(shù)
            l = Math.abs(e), //取絕對(duì)值,l-1就是0的個(gè)數(shù)
            sign = e/l,          //判斷正負(fù)
            coeff_array = parts[0].split('.');   //將系數(shù)按照小數(shù)點(diǎn)拆分
          if(sign === -1) {           //如果是小數(shù)
            num = zero + '.' + new Array(l).join(zero) + coeff_array.join('');   //拼接字符串厉萝,如果是小數(shù)恍飘,拼接0和小數(shù)點(diǎn)
          } else {
            var dec = coeff_array[1];  
            if(dec) l = l - dec.length;  //如果是整數(shù),將整數(shù)除第一位之外的非零數(shù)字計(jì)入位數(shù)谴垫,相應(yīng)的減少0的個(gè)數(shù)
            num = coeff_array.join('') + new Array(l+1).join(zero);    //拼接字符串章母,如果是整數(shù),不需要拼接小數(shù)點(diǎn)
          }
        }
        return num;
      }

通過這兩個(gè)方法可以解決項(xiàng)目中遇到的兩個(gè)問題翩剪,驗(yàn)證有效乳怎,在此記錄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末前弯,一起剝皮案震驚了整個(gè)濱河市蚪缀,隨后出現(xiàn)的幾起案子秫逝,更是在濱河造成了極大的恐慌,老刑警劉巖询枚,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件违帆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡金蜀,警方通過查閱死者的電腦和手機(jī)刷后,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渊抄,“玉大人尝胆,你說我怎么就攤上這事』よ耄” “怎么了含衔?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)二庵。 經(jīng)常有香客問我抱慌,道長(zhǎng),這世上最難降的妖魔是什么眨猎? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮强经,結(jié)果婚禮上睡陪,老公的妹妹穿的比我還像新娘。我一直安慰自己匿情,他們只是感情好兰迫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炬称,像睡著了一般汁果。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玲躯,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天据德,我揣著相機(jī)與錄音,去河邊找鬼跷车。 笑死棘利,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的朽缴。 我是一名探鬼主播善玫,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼密强!你這毒婦竟也來了茅郎?” 一聲冷哼從身側(cè)響起蜗元,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎系冗,沒想到半個(gè)月后奕扣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡毕谴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年成畦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涝开。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡循帐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出舀武,到底是詐尸還是另有隱情拄养,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布银舱,位于F島的核電站瘪匿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏寻馏。R本人自食惡果不足惜棋弥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诚欠。 院中可真熱鬧顽染,春花似錦、人聲如沸轰绵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽左腔。三九已至唧垦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間液样,已是汗流浹背振亮。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鞭莽,地道東北人双炕。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像撮抓,于是被迫代替她去往敵國(guó)和親妇斤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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