今天業務忽然發現10.155這個數字四捨五入保留兩位小數有問題,結果是10.15,沒有四捨五入。當時用的是toFixed(2)方法,查了一個文檔發現js精度計算有問題致使的。bash
後來在網上查了一些資料,找到了一個簡單的方法ui
Math.round(value * 100) / 100
複製代碼
可是這樣仍是不行,發現10.155仍是會變成10.15,我一度懷疑是Math.round方法的問題,試了一些數,都沒問題,而後試了一下10.155*100,結果居然是1015.4999999999999,Math.round方法沒問題,是計算的問題。而後又在網上找別的解決方案,基本都有一些小問題,而後決定本身寫一個方法。spa
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}`
}
}
}
複製代碼