在js中number
类型包含了整数类型, 浮点数类型等等. 一般只有在浮点型会出现精度问题.
我们在项目中通常会遇见这种问题:
let price = 65 * 0.119; // 计算出一个价格
price = price.toFixed(2); // 期望得到7.74 实际得到7.73
为什么会有这样的一个结果呢, 原因就是计算机在工作时都会将这些十进制先转化为二进制, 然后再进行计算. 浮点型数值在转化二进制后得到的就是一个近似值而不是准确值. 两个近似值再进行运算, 得到的结果当然也就不是你所想得到的那个值. 这里也就能想明白为什么存在精度问题了, 不是同一个世界, 二进制与十进制. 计算时在二进制的世界中, 得到显示的值则是在十进制的世界中.
在上面我们计算 价格 时四舍五入得到7.73
, 其实我们想得到的是7.74
. 这里js中的toFixed
所计算的四舍五入为 银行家算法 四舍六入五取偶 和我们普遍认为的四舍五入是有一定区别的.
还有一点需要注意的则是toFixed
是 number类型 的方法, 然而方法得到的值则是一个string类型.
把小数放到位整数(乘倍数),再缩小回原来倍数(除倍数)
就衍生出下面方法:
const toFixed = (num, s) => {
const mulriple = Math.pow(10, s);
let res = num * mulriple;
res = Math.round(res) / mulriple;
return res.toFixed(s);
};
let price = 65 * 0.119;
price = toFixed(price, 2); // 7.74
也可以直接修改js中的toFixed
方法:
// 原始版本
const oldToFixed = Number.prototype.toFixed;
Number.prototype.toFixed = function (s) {
const mulriple = Math.pow(10, s);
let res = this * mulriple;
res = Math.round(res) / mulriple;
return oldToFixed.call(res, s);
};
let price = (65 * 0.119).toFixed(2); // 7.74