关于js保留两位小数toFixed()方法的bug 以及解决办法

最近在做小程序的一个项目 老大要求所有的计算出来的金钱数字都要保留两位小数点,自然而然想到了js的toFixed() 方法,然而既然写了这个文章结局肯定不想而知......闲言少叙 上代码
还是再说几句吧 好歹描述一下 业务场景 复现一下过程, 过程是这个样子滴
后台设置了折扣的金额 8.745折 我这个时候订单的金额是10RMB 结果就是

let discount = 8.745; // 优惠折扣
let money = 10;// 订单金额
let price = discount/10*10; // 实际支付金额
console.log(price) // 实际支付的金额  8.745RMB
/***需求 (保留两位小数)***/
// 最开始的天真想法
let price = (discount/10*10).toFixed(2)
console.log(price) // 8.74

传到后台发现后台校验的金额和前台传的对不上......尴尬的一比 然后开始一顿笔算,和后台对结果,后来发现了问题 后台的结果是 8.75 前台是8.74 差了一分钱,发现前台计算出来的结果保留两位小数之后的值没有四舍五入 ,可是我又在想 toFixed() 是四舍五入的啊 为此 去测试了一下

(8.755).toFixed(2) // 8.76
(8.745).toFixed(2) // 8.74
(8.746).toFixed(2) // 8.75

得出来的解困就是这样 在3为小数的情况下

第二位小数小于5 第三位小数<=5 结果是不四舍五入的

这就尴尬了啊!
后来弄明白了是js计算的bug,js计算浮点数精度丢失的问题 网上的库解决这个一搜一大堆,但是咱们的需求是保留两位小数啊 所以结合一下...

接下来就说一下小老弟的解决办法

function accDiv(arg1,arg2){  
 var t1=0,t2=0,r1,r2;  
 try{t1=arg1.toString().split(".")[1].length}catch(e){}  
 try{t2=arg2.toString().split(".")[1].length}catch(e){}  
 with(Math){  
 r1=Number(arg1.toString().replace(".",""))  
 r2=Number(arg2.toString().replace(".","")) 
 return accMul((r1/r2),pow(10,t2-t1));  
 }  
 } 
// 乘法
function accMul(arg1,arg2)  
 {  
 var m=0,s1=arg1.toString(),s2=arg2.toString();  
 try{m+=s1.split(".")[1].length}catch(e){}  
 try{m+=s2.split(".")[1].length}catch(e){}  
 return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)  
 }  
/**
  以上是网上copy出来的 
  以下是我的
**/
function toFixedTwo(n){
  if(!isNaN(n)){
    console.error("Error:n not is Number")  
    return false
  }
  return  (Math.round(accMul(n,100))/100).toFixed(2)
}

也算是历经磨难解决了吧!
在js浮点数计算精度丢失问题导致结果异常和不准确 也是坑了我好几次了
ps:题外话 四月不减肥 五月徒伤悲 减肥开始了!!

你可能感兴趣的:(关于js保留两位小数toFixed()方法的bug 以及解决办法)