国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript解決浮點數計算不準確問題的方法分析

2019-11-19 13:31:42
字體:
來源:轉載
供稿:網友

本文實例講述了JavaScript解決浮點數計算不準確問題的方法。分享給大家供大家參考,具體如下:

最近在學習electron框架,想利用這個框架做一個簡單的計算器demo。當我對小數進行運算時,發現了一個問題。

0.1+0.2=?

輸出結果是:0.30000000000000004

為什么會這樣呢?

其實對于浮點數的四則運算,幾乎所有的編程語言都會有類似精度誤差的問題,只不過在 C++/C#/Java 這些語言中已經封裝好了方法來避免精度的問題,而 JavaScript 是一門弱類型的語言,從設計思想上就沒有對浮點數有個嚴格的數據類型,所以精度誤差的問題就顯得格外突出。

首先我們分析一下為什么會出現這個精度誤差?

首先,我們要站在計算機的角度思考 0.1 + 0.2 這個看似小兒科的問題。我們知道,能被計算機讀懂的是二進制,而不是十進制,所以我們先把 0.1 和 0.2 轉換成二進制看看:

0.1 => 0.0001 1001 1001 1001..(無限循環)
0.2 => 0.0011 0011 0011 0011…(無限循環)

上面我們發現0.1和0.2轉化為二進制之后,變成了一個無限循環的數字,這在現實生活中,無限循環我們可以理解,但計算機是不允許無限循環的,對于無限循環的小數,計算機會進行舍入處理。進行雙精度浮點數的小數部分最多支持52位,所以兩者相加之后得到這么一串 0.0100110011001100110011001100110011001100110011001100 因浮點數小數位的限制而截斷的二進制數字,這時候,我們再把它轉換為十進制,就成了 0.30000000000000004。

知道了浮點數產生的原因,那么如何處理這個問題呢?

方法1:通過toFixed(num)方法來保留小數。因為這個方法是根據四舍五入來保留小數的,所以最后的計算結果不精確。

方法2:把要計算的數字升級(乘以10的n次冪)成計算機能夠精確識別的整數,計算完以后再降級,推薦使用這一種方法。具體代碼如下(主要有3個方法):

/*判斷obj是否為一個整數*/function isInteger(obj){  return Math.floor(obj) === obj;}/*** 將一個浮點數轉換成整數,返回整數和倍數* 如 3.14 》》314 倍數是100**/function toInteger(floatNum){  var ret = {times:1,num:0};  //是整數  if(isInteger(floatNum)){    ret.num = floatNum;    return ret;  }  var strfi = floatNum + '';  //查找小數點的下標  var dotPos = strfi.indexOf('.');  console.log('dotPos===='+dotPos);  //獲取小數的位數  var len = strfi.substr(dotPos+1).length;  console.log('len===='+len);  //Math.pow(10,len)指定10的len次冪。  var time = Math.pow(10,len);  //將浮點數轉化為整數  var intNum = parseInt(floatNum*time + 0.5,10);  console.log('intNum===='+intNum);  ret.times = time;  ret.num = intNum;  return ret;}/***進行運算*三個參數分別是要運算的兩個數和運算符*/function operation(a,b,op){  var o1 = toInteger(a);  var o2 = toInteger(b);  var n1 = o1.num;  var n2 = o2.num;  var t1 = o1.times;  var t2 = o2.times;  var max = t1 > t2 ? t1 : t2;  var result = null;  switch(op){    case 'add':      if(t1 === t2){        result = n1 + n2;      }else if(t1 > t2){        result = n1 + n2 * (t1/t2);      }else{        result = n1 * (t2/t1) + n2;      }      return result / max;      break;    case 'subtract':      if(t1 === t2){        result = n1 - n2;      }else if(t1 > t2){        result = n1 - n2 * (t1/t2);      }else{        result = n1 * (t2/t1) - n2;      }      return result / max;      break;    case 'multiply':      result = (n1 * n2)/(t1 * t2);      return result;      break;    case 'divide':      result = (n1 / n2)/(t2 / t1);      return result;      break;  }}

更多關于JavaScript相關內容感興趣的讀者可查看本站專題:《JavaScript數學運算用法總結》、《JavaScript數據結構與算法技巧總結》、《JavaScript數組操作技巧總結》、《JavaScript事件相關操作與技巧大全》、《JavaScript操作DOM技巧總結》及《JavaScript字符與字符串操作技巧總結

希望本文所述對大家JavaScript程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武鸣县| 湛江市| 永昌县| 金山区| 平邑县| 绥棱县| 沙湾县| 红桥区| 宁夏| 高安市| 松原市| 莱州市| 安阳市| 天全县| 金堂县| 拉萨市| 抚远县| 陆丰市| 盱眙县| 阳高县| 广饶县| 克什克腾旗| 芜湖市| 阜康市| 辽阳市| 高雄市| 福清市| 通渭县| 永新县| 古浪县| 东丰县| 布尔津县| 宁津县| 缙云县| 交口县| 岳普湖县| 湖南省| 镇原县| 盐山县| 西乌珠穆沁旗| 静乐县|