• 解决js加减乘除精度丢失问题


    公共类, 将科学计数法的数字转为字符串(以下加减乘除依赖该方法)

    var toNonExponential = (num)=> {
        if(num == null) {
            return num;
        }
        if(typeof num == "number") {
            var m = num.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/);
            return num.toFixed(Math.max(0, (m[1] || '').length - m[2]));
        }else {
            return num;
        }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    乘(以下加减除依赖该方法)

    var floatMultiply = (arg1, arg2) => {
        arg1 = Number(arg1);
        arg2 = Number(arg2);
        if ((!arg1 && arg1!==0) || (!arg2 && arg2!==0)) {
            return null;
        }
        arg1 = toNonExponential(arg1);
        arg2 = toNonExponential(arg2);
        var n1, n2;
        var r1, r2; // 小数位数
        try {
            r1 = arg1.toString().split(".")[1].length;
        } catch (e) {
            r1 = 0;
        }
        try {
            r2 = arg2.toString().split(".")[1].length;
        } catch (e) {
            r2 = 0;
        }
        n1 = Number(arg1.toString().replace(".", ""));
        n2 = Number(arg2.toString().replace(".", ""));
        return n1 * n2 / Math.pow(10, r1 + r2);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    var floatDivide = (arg1, arg2) => {
        arg1 = Number(arg1);
        arg2 = Number(arg2);
        if (!arg2) {
            return null;
        }
        if (!arg1 && arg1!==0) {
            return null;
        }else if(arg1===0) {
            return 0;
        }
        arg1 = toNonExponential(arg1);
        arg2 = toNonExponential(arg2);
        var n1, n2;
        var r1, r2; // 小数位数
        try {
            r1 = arg1.toString().split(".")[1].length;
        } catch (e) {
            r1 = 0;
        }
        try {
            r2 = arg2.toString().split(".")[1].length;
        } catch (e) {
            r2 = 0;
        }
        n1 = Number(arg1.toString().replace(".", ""));
        n2 = Number(arg2.toString().replace(".", ""));
        return floatMultiply((n1 / n2), Math.pow(10, r2 - r1));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    var floatAdd = (arg1, arg2) => {
        arg1 = Number(arg1) || 0;
        arg2 = Number(arg2) || 0;
        arg1 = toNonExponential(arg1);
        arg2 = toNonExponential(arg2);
        var r1, r2, m;
        try {
            r1 = arg1.toString().split(".")[1].length;
        } catch (e) {
            r1 = 0;
        }
        try {
            r2 = arg2.toString().split(".")[1].length;
        } catch (e) {
            r2 = 0;
        }
        m = Math.pow(10, Math.max(r1, r2));
        return (floatMultiply(arg1, m) + floatMultiply(arg2, m)) / m;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    var floatSub = (arg1, arg2) => {
        arg1 = Number(arg1) || 0;
        arg2 = Number(arg2) || 0;
        arg1 = toNonExponential(arg1);
        arg2 = toNonExponential(arg2);
        var r1, r2, m, n;
        try {
            r1 = arg1.toString().split(".")[1].length;
        } catch (e) {
            r1 = 0;
        }
        try {
            r2 = arg2.toString().split(".")[1].length;
        } catch (e) {
            r2 = 0;
        }
        m = Math.pow(10, Math.max(r1, r2));
        // 动态控制精度长度
        n = (r1 >= r2) ? r1 : r2;
        return ((floatMultiply(arg1, m) - floatMultiply(arg2, m)) / m).toFixed(n);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    参考:https://blog.csdn.net/ycclydy/article/details/123580326

  • 相关阅读:
    前端基础JS
    java基于ssm的奖学金管理系统-计算机毕业设计
    基于springboot+vue社区疫情防控系统
    设计模式-观察者模式
    Visual Studio 和 VSCode哪个更好?
    基于JAVA医院患者管理系统计算机毕业设计源码+系统+数据库+lw文档+部署
    Git纯操作版 项目添加和提交、SSH keys添加、远程仓库控制、冲突解决、IDEA连接使用
    nacos注册中心
    java毕业设计宝马官网Mybatis+系统+数据库+调试部署
    基于单片机的恒流开关电源 BUCK电路设计
  • 原文地址:https://blog.csdn.net/qq_44063746/article/details/132889748