• 两种精度丢失问题


    最近在工作中频繁的遇到精度问题

    1、在js中,当两个带小数点的数值进行加减运算时,在某些特殊情况下如小数点末尾为9或相加为9等情况,则存在精度问题,结果为两位小数点的数据计算出来的结果为很长一串。

    解决办法:由于业务涉及到钱,所以不能使用四舍五入,只能采取直接截取或别的,目的是保留两位小数。

    在尝试多种方法后 如使用toFix方法,转换成decimal等后均不能解决问题,后来自己实现了两个方法,一个相加一个相减。方法的核心是根据小数位数扩大相应倍数进行计算。

    方法如下:

    /**
    * 加法运算,避免数据相加小数点后产生多位数和计算精度损失。
    *
    * @param num1加数1 | num2加数2
    */
    function numAdd(num1, num2) {
    var baseNum, baseNum1, baseNum2;
    try {
    baseNum1 = num1.toString().split(".")[1].length;
    } catch (e) {
    baseNum1 = 0;
    }
    try {
    baseNum2 = num2.toString().split(".")[1].length;
    } catch (e) {
    baseNum2 = 0;
    }
    baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
    return (num1 * baseNum + num2 * baseNum) / baseNum;
    };
    /**
    * 加法运算,避免数据相减小数点后产生多位数和计算精度损失。
    *
    * @param num1被减数 | num2减数
    */
    function numSub(num1, num2) {
    var baseNum, baseNum1, baseNum2;
    var precision;// 精度
    try {
    baseNum1 = num1.toString().split(".")[1].length;
    } catch (e) {
    baseNum1 = 0;
    }
    try {
    baseNum2 = num2.toString().split(".")[1].length;
    } catch (e) {
    baseNum2 = 0;
    }
    baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
    precision = (baseNum1 >= baseNum2) ? baseNum1 : baseNum2;
    return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision);
    };

    2、今日在mysql中也遇到类似的问题。由于也涉及到金钱,所以不能马虎。
    select 20.43+'1.99',20.43+1.99得到的结果不一样。前者是数字与字符串数字相加,后者是纯数字类型相加。但是前者产生了精度问题。
    得到的结果如下

    多次试验之后发现,并不是所有的数字与字符串相加都会有精度问题,似乎当有一个小数的末尾为9或者小数点后一位相加等于9时会出现此种问题。猜想估计是mysql中字符串转数字的算法问题导致的。

    经过db2数据库的校验,此种计算在db2中不存在问题。

    解决办法:结果保留两位小数。使用truncate计算之后截取。

    select 20.43+'1.99',truncate('1.99'+20.43,2),188.48+'3000.01',truncate(188.48+'3000.01',2)

    cast函数和convert函数不满足要求。

    由于多次遇到,故作记录。

    
    
  • 相关阅读:
    mysql 在orderby和limit混合使用时重复数据问题
    springboot启动类 注解
    redis RDB和AOF两种持久化的区别
    C#解析逻辑字符串【x>y&&a>b||p=r】
    删除例如联想笔记本系统隐藏分区
    通过贝叶斯算法实现自动识别类别
    将可执行exe文件注册成windows服务
    Windows10中的IIS10安装php manager和IIS URL Rewrite 2.0组件的方法
    添加钩子监听全局鼠标或键盘事件
    C# DateTime.Now和DateTime.UtcNow的区别
  • 原文地址:https://www.cnblogs.com/hzzll/p/10032641.html
Copyright © 2020-2023  润新知