中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-10-08 21:51:44 來源:腳本之家 閱讀:167 作者:zhang070514 欄目:web開發

本文實例講述了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程序設計有所幫助。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泗洪县| 富锦市| 甘泉县| 博客| 罗平县| 奉贤区| 道真| 梁山县| 绥滨县| 长宁县| 应用必备| 洪雅县| 论坛| 青浦区| 雷山县| 丹东市| 桐柏县| 长寿区| 和平县| 马尔康县| 永德县| 淳化县| 巴中市| 沾益县| 澄迈县| 喀喇| 红原县| 阳新县| 阳曲县| 微博| 宁蒗| 射洪县| 康平县| 铜川市| 瑞昌市| 乐亭县| 六盘水市| 永丰县| 宁城县| 禄丰县| 凉城县|