以下是在项目中遇到的问题

购物车结算时,商品价格(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)//除
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐