• 小数十位之内丢失精度问题解决


     
        accAdd(m) {  
            /**
        * m=[0.55,0.584]
             * 先声明俩临时变量
             * temp 临时 sum 合 Integer 整数 Decimal 小数
             * 也就是声明了两个临时变量  一个是求和整数 一个是求和小数
             * 注意这俩变量的类型 是 bigint
             * 科普时间到
             * bigint 是一个 js 新加的数据类型 ie 不支持哟
             * bigint 可以特别特别的长  但是他没有小数 没有负数
             * 一般做小数操作的时候都是分开操作或者直接先把小数位去掉 比如乘一个大数
             * 我这次选择了分开操作因为可能输入的小数就很大所以输入框必须是字符串的那么分开操作方便
             * bigint 的写法就是数字后加个 n  后面的代码你会看到这个写法的
             */
            let tempSumInteger = BigInt(0)
            let tempSumDecimal = BigInt(0)
            const regNonZero = /^[1-9][0-9]*([\.]\d*)?$/   //非0开头的数字
            const regZero = /^[0]*([\.]\d*)?$/  //0开头的小数
            m.forEach(element => {
              //看看是不是能则上 上面两种规则 则上就处理 则不上就不管了直接忽略了
              //以防万一强转个字符串类型
              element = String(element)
              if (regNonZero.test(element) || regZero.test(element)) {
                /**
                 * 用小数点切一下 取一下整数位和小数位  因为数字太长分开处理
                 * 整数位
                 * 取强转成 bgiint 然后累加一下  取不到的时候就默认给0n   敲黑板 number 类型不能和 bigint 混合运算 所以默认值要写 0n
                */
                tempSumInteger += BigInt(element.split('.')[0] ?? 0n)
     
                //小数位
     
                //先取出来当前数的小数位并转成 bigint
                let tempDecimal = BigInt(element.split('.')[1] ?? 0n)
                //取一下当前缓存的小数位的和的长度
                const tempSumDecimalLength = tempSumDecimal.toString().length
                //取一下当前小数位的长度
                const tempDecimalLength = tempDecimal.toString().length
                //取一下当前小数和缓存的小数 长度的最大值
                const length = Math.max(tempSumDecimalLength, tempDecimalLength)
                //甭管是谁 都统一补一波 0
                tempSumDecimal = tempSumDecimal * BigInt(10 ** (length - tempSumDecimalLength))
                tempDecimal = tempDecimal * BigInt(10 ** (length - tempDecimalLength))
                // 计算一下小数位的合 缓存一下
                let tempDecimalSum = tempSumDecimal + tempDecimal
                //对比一下求完和的小数位是不是变长了
                if (tempDecimalSum.toString().length > length) {
                  //变长了的话就把多出来的扔给整数位
     
                  //取长度差
                  const DecimalDifference = tempDecimalSum.toString().length - length
                  //取出来多的部分  并且加给缓存的整数位
                  tempSumInteger += BigInt(tempDecimalSum.toString().slice(0, DecimalDifference))
                  //把剩下的给小数位
                  tempDecimalSum = BigInt(tempDecimalSum.toString().slice(DecimalDifference))
                }
                //小数替换一下  妈蛋就这写错了  写了个+= 找了半天 好气
                tempSumDecimal = tempDecimalSum
              }
            })
            //输出的时候拼接一下整数位 小数点 小数位 即可出锅
            return `${tempSumInteger.toString()}.${tempSumDecimal.toString()}`
          }
  • 相关阅读:
    Java 得到指定时间加半个小时之后得时间
    MySQL查询point类型类型的坐标,返回经度纬度
    MySQL通过实体经纬度字段插入数据库point类型的经纬度字段
    MySQL通过POIN数据类型查询指定范围内数据
    Java 根据两个经纬度,得到两点距离
    mysql通过经纬度查询400公里范围内的小区
    位运算
    Hibernate多对多删除问题的解决
    mysql 中 时间和日期函数
    Struts2数据传输的背后机制:ValueStack(值栈)
  • 原文地址:https://www.cnblogs.com/PoisonousMushrooms/p/15831703.html
Copyright © 2020-2023  润新知