zoukankan      html  css  js  c++  java
  • JS加减乘除精度丢失问题解决

    一、前言

    ​ 工作中经常遇到用户输入后实时计算结果,比如输入单价和数量后自动计算总价,部分情况下会出现丢失精度的问题。解决方式为将小数放大为整数,计算完后再缩小。

    二、解决

       /*
        * 加法
        * add(0.123 , 1.4567 , 10.56789)
        */
        function add(...val) {
          let sum = 0,
            maxDecimalLength = getMaxDecimalLength(...val)
    
          val.forEach((x, index) => {
            // 所有数值转为整数计算
            sum += Math.round(x * Math.pow(10, maxDecimalLength))
          })
    
          return sum / Math.pow(10, maxDecimalLength)
        }
    
        /*
        * 减法
        * subtract(0.123 , 1.4567 , 10.56789)
        */
        function subtract(...val) {
          let sum,
            maxDecimalLength = getMaxDecimalLength(...val)
    
          val.forEach((x, index) => {
            let nurVal = Math.round(x * Math.pow(10, maxDecimalLength));
    
            if (index === 0)
              sum = nurVal
            else
              sum -= nurVal
          })
    
          return sum / Math.pow(10, maxDecimalLength)
        }
    
        /*
        * 乘法
        * multiply(0.123 , 1.4567 , 10.56789)
        */
        function multiply(...val) {
          let sum,
            decimalLengthSum = 0
    
          val.forEach((x, index) => {
            // 获取当前小数位长度
            let decimalLength = getMaxDecimalLength(x)
            // 将当前数变为整数
            let nurVal = Math.round(x * Math.pow(10, decimalLength));
    
            decimalLengthSum += decimalLength
    
            if (index === 0)
              sum = nurVal
            else
              sum *= nurVal
          })
    
          return sum / Math.pow(10, decimalLengthSum)
    
        }
    
        /*
        * 除法
        * divide(0.123 , 1.4567 , 10.56789)
        */
        function divide(...val) {
    
          let sum = 0,
            decimalLengthSum = 0
    
          val.forEach((x, index) => {
            // 获取当前小数位长度
            let decimalLength = getMaxDecimalLength(x)
            // 将当前数变为整数
            let nurVal = Math.round(x * Math.pow(10, decimalLength));
    
            if (index === 0) {
              decimalLengthSum = decimalLength
    
              sum = nurVal
            } else {
              decimalLengthSum -= decimalLength
              sum /= nurVal
            }
          })
    
          return sum / Math.pow(10, decimalLengthSum)
    
        }
    
        /*
        * 获取小数位数
        */
        function getMaxDecimalLength(...val) {
          // 最大小数位长度
          let maxDecimalLength = 0
    
          val.forEach((x) => {
    
            const strVal = x.toString(),
              dotIndex = strVal.indexOf('.')
            if (dotIndex > -1) {
              // 获取当前值小数位长度
              let curDecimalLength = strVal.length - 1 - dotIndex
    
              if (curDecimalLength > maxDecimalLength) {
                maxDecimalLength = curDecimalLength
              }
            }
          })
    
          return maxDecimalLength
    
        }
    
  • 相关阅读:
    Spring-3
    Spring-2
    Spring-1
    SpringMVC-视图解析器
    SpringMVC起步
    jsp中引用的jstl 和fmt标签-详解
    Spring-JDBCTemplate介绍
    Spring框架详解介绍-基本使用方法
    VIP邮箱有什么好处,北京外贸邮箱品牌原来这个最好用?
    网易企业邮箱申请,申请企业邮箱流程分享~
  • 原文地址:https://www.cnblogs.com/gaozejie/p/14963452.html
Copyright © 2011-2022 走看看