以下是在项目中遇到的问题
购物车结算时,商品价格(33.01)-优惠券价格(5),本应该是28.01,但是实际的结果是28.009999999999998
之前真没遇到过这种问题,查了很多资料才了解到js 小数相加减是会出现精度丢失的问题
案例
本案例是在浏览器控制台里打印
出现这种问题的原因,查看详细原因(链接)
原因其实就是js number类型运算都需要先将十进制转二进制
但小数点后的位数转二进制会出现无限循环的问题,只能舍0入1,所以会出现小数点丢失问题,感兴趣的可以自己研究,链接在上面。
解决方法
1.保留小数位数toFixed()
注意:toFixed()保留完是字符串,需要转数字类型
2.可以通过先乘10的倍数,然后再除
比如 我要保留两位小数 那我就乘100,运算完后再除100
虽然繁琐,但是有效
封装成方法
//num1 num2传入两个值 symbol +-*/符号
function amend(num1,num2,symbol){
var str1=num1.toString(),str2=num2.toString(),result,str1Length,str2Length
//解决整数没有小数点方法
try {str1Length= str1.split('.')[1].length} catch (error) {str1Length=0}
try {str2Length= str2.split('.')[1].length} catch (error) {str2Length=0}
var step=Math.pow(10,Math.max(str1Length,str2Length))
//
console.log(step);
switch (symbol) {
case "+":
result= (num1*step+num2*step)/step
break;
case "-":
result= (num1*step-num2*step)/step
break;
case "*":
result= ((num1*step)*(num2*step)) / step/step
break;
case "/":
result= (num1*step)/(num2*step)
break;
default:
break;
}
return result
}
console.log(amend(0.1,0.2,"+"));
项目中解决精度丢失问题 请使用mathjs 最全的Mathjs资料,js的Math已经不够用了(大佬整理的文档)
vue中使用mathjs
1.安装math.js
npm install mathjs
2.新建math.js配置
const $math = require('mathjs')
export const math = {
add () {
return comp('add', arguments)
},
subtract () {
return comp('subtract', arguments)
},
multiply () {
return comp('multiply', arguments)
},
divide () {
return comp('divide', arguments)
}
}
function comp (_func, args) {
let t = $math.chain($math.bignumber(args[0]))
for (let i = 1; i < args.length; i++) {
t = t[_func]($math.bignumber(args[i]))
}
// 防止超过6位使用科学计数法
return parseFloat(t.done())
}
3.引入math.js
import { math } from '@/utils/math.js'
math.js使用
math.add(a+b)//加
math.subtract(a-b)//减
math.multiply(a*b)//乘
math.divide(a/b)//除