今天业务忽然发现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}`
}
}
}
复制代码