js保留小數四捨五入問題(內含解決方法)

1.原由

今天業務忽然發現10.155這個數字四捨五入保留兩位小數有問題,結果是10.15,沒有四捨五入。當時用的是toFixed(2)方法,查了一個文檔發現js精度計算有問題致使的。bash

2.解決問題

後來在網上查了一些資料,找到了一個簡單的方法ui

Math.round(value * 100) / 100
複製代碼

可是這樣仍是不行,發現10.155仍是會變成10.15,我一度懷疑是Math.round方法的問題,試了一些數,都沒問題,而後試了一下10.155*100,結果居然是1015.4999999999999,Math.round方法沒問題,是計算的問題。而後又在網上找別的解決方案,基本都有一些小問題,而後決定本身寫一個方法。spa

3.代碼

try {
  const result = toDecimal(".995");
  console.log(result); //1.00
} catch (error) {
  console.log(error);
}

// 保留任意位小數
function toDecimal(number, precision = 2) {
  const temp = number;
  number = Number(number);
  // 判斷是否爲數字,不是數字拋出異常
  if (Number.isNaN(number)) {
    console.log("無效的數字:" + temp);
    throw new Error("無效的數字:" + temp);
  }

  number = String(number);
  let numbers = number.split(".");
  // 若是不是小數,補充對應的0
  if (numbers.length === 1) {
    return number + "." + "0".repeat(precision)
  } else {
    // 若是是小數 但位數比要保留的位數少 也是要補0
    if (numbers[1].length < precision) {
      return number + "0".repeat(precision - numbers[1].length);
    } else {
      // 取整數部分
      let intNumber = parseInt(number.split(".")[0]);
      // 取小數部分
      let decimal = number.split(".")[1];
      // 取出要保留的小數
      let frontDecimal = parseInt(decimal.substr(0, precision));
      // 去除要保留小數的後一位 
      const lastDecimal = parseInt(decimal.substr(precision, 1));
      // 若是最後覺得大於5 就進位
      if (lastDecimal >= 5) {
        frontDecimal += 1;
      }
      //判斷小數部位是否須要進位 相似於19.996 保留2位小數 就是20.00
      if (frontDecimal === Math.pow(10, precision)) {
        frontDecimal = "0".repeat(precision)
        intNumber += 1;
      }
      //處理 0.015 0.009 保留的小數中有0出現的狀況
      frontDecimal = "0".repeat(precision - String(frontDecimal).length) + frontDecimal;

      return `${intNumber}.${frontDecimal}`
    }
  }
}
複製代碼
相關文章
相關標籤/搜索