Skip to content

Latest commit

 

History

History
49 lines (41 loc) · 1.89 KB

四舍五入问题.md

File metadata and controls

49 lines (41 loc) · 1.89 KB

精度问题

在js中number类型包含了整数类型, 浮点数类型等等. 一般只有在浮点型会出现精度问题. 我们在项目中通常会遇见这种问题:

let price = 65 * 0.119; // 计算出一个价格

price = price.toFixed(2); // 期望得到7.74 实际得到7.73

为什么会有这样的一个结果呢, 原因就是计算机在工作时都会将这些十进制先转化为二进制, 然后再进行计算. 浮点型数值在转化二进制后得到的就是一个近似值而不是准确值. 两个近似值再进行运算, 得到的结果当然也就不是你所想得到的那个值. 这里也就能想明白为什么存在精度问题了, 不是同一个世界, 二进制与十进制. 计算时在二进制的世界中, 得到显示的值则是在十进制的世界中.

四舍五入问题

在上面我们计算 价格 时四舍五入得到7.73, 其实我们想得到的是7.74. 这里js中的toFixed所计算的四舍五入为 银行家算法 四舍六入五取偶 和我们普遍认为的四舍五入是有一定区别的. 还有一点需要注意的则是toFixednumber类型 的方法, 然而方法得到的值则是一个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