zoukankan      html  css  js  c++  java
  • js控制精度的加减乘除:js浮点数计算问题

    //加法函数
            function accAdd(arg1, 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 (arg1 * m + arg2 * m) / m;
            }
    
            //给Number类型增加一个add方法,,使用时直接用 .add 即可完成计算。
            Number.prototype.add = function (arg) {
                return accAdd(arg, this);
            };
    
            //减法函数
            function Subtr(arg1, 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));
                //last modify by deeka
                //动态控制精度长度
                n = (r1 >= r2) ? r1 : r2;
                return ((arg1 * m - arg2 * m) / m).toFixed(n);
            }
    
            //给Number类型增加一个add方法,,使用时直接用 .sub 即可完成计算。
            Number.prototype.sub = function (arg) {
                return Subtr(this, arg);
            };
    
            //乘法函数
            function accMul(arg1, arg2) {
                var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
                try {
                    m += s1.split(".")[1].length;
                }
                catch (e) {
                }
                try {
                    m += s2.split(".")[1].length;
                }
                catch (e) {
                }
                return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
            }
    
            //给Number类型增加一个mul方法,使用时直接用 .mul 即可完成计算。
            Number.prototype.mul = function (arg) {
                return accMul(arg, this);
            };
    
            //除法函数
            function accDiv(arg1, arg2) {
                var t1 = 0, t2 = 0, r1, r2;
                try {
                    t1 = arg1.toString().split(".")[1].length;
                }
                catch (e) {
                }
                try {
                    t2 = arg2.toString().split(".")[1].length;
                }
                catch (e) {
                }
                with (Math) {
                    r1 = Number(arg1.toString().replace(".", ""));
                    r2 = Number(arg2.toString().replace(".", ""));
                    return (r1 / r2) * pow(10, t2 - t1);
                }
            }
    
            //给Number类型增加一个div方法,,使用时直接用 .div 即可完成计算。
            Number.prototype.div = function (arg) {
                return accDiv(this, arg);
            };
    
            function setNumAndWeight(num, weight, index, obj) {
                $(obj).parent().next("td").text(getFloatByNum(weight, 4));
                var html = "件数:" + num + "<br>" + "重量:" + getFloatByNum(weight, 4);
                $("tr.tr-" + index).children().eq(4).html(html);
            }
    
            //强制制保留4位小数,第5位直接舍去。如:2,会在2后面补上00.即2.00
            function toDecimal4(x) {
                var f = parseFloat(x);
                if (isNaN(f)) {
                    return false;
                }
                var f = Math.floor(x * 10000) / 10000;
                var s = f.toString();
                var rs = s.indexOf('.');
                if (rs < 0) {
                    rs = s.length;
                    s += '.';
                }
                while (s.length <= rs + 4) {
                    s += '0';
                }
                return s;
            }

    调用,直接用:

     var weight = parseFloat(perWeight).mul(parseInt(num).add(onboardNum)).sub(onboardWeight);

    //加法示例(其它的都类似)
    function calculate() {
        //数字1
        var num1 = 10;
        //数字2
        var num2 = 5;
        //计算 num1 + num2
        alert(num1.add(num2));
    }

    2、其他解释:

    大多数语言在处理浮点数的时候都会遇到精度问题,但是在JS里似乎特别严重,来看一个例子

    alert(45.6*13);
    

    结果居然是592.800000000001,当然加法之类的也会有这个问题

    那这是js的错误吗?

    当然不是,你的电脑做着正确的二进制浮点运算,但问题是你输入的是十进制的数,电脑以二进制运算,这两者并不是总是转化那么好的,有时候会得到正确的结果,但有时候就不那么幸运了

    alert(0.7+0.1);//输出0.7999999999999999
    alert(0.6+0.2);//输出0.8
    
    

    你输入两个十进制数,转化为二进制运算过后再转化回来,在转化过程中自然会有损失了

    但一般的损失往往在乘除运算中比较多,而JS在简单的加减法里也会出现这类问题,你也看到了,这个误差也是非常小的,但是却是不该出现的

    那该怎么解决呢,ECMA4似乎给了解决方法,但是现在倒不是那么实用的

    一种方法,比如0.7+0.1,先把0.1和0.7都乘10,加完之后再除10

    另外可以自己写点函数来解决这个问题,自己百度谷歌一下应该有很多,但是最好还是不要用JS做一些复杂的浮点运算,毕竟JS更多的作用不在于此

  • 相关阅读:
    单片机学习01__跑起你的流水灯
    python2与python3共存
    rpi-kali 搭建网络靶场
    P3388 【模板】割点(割顶)
    P3387 【模板】缩点
    P1069 细胞分裂
    The Unique MST[不严格的次小生成树]
    P3369 【模板】普通平衡树
    Netty的线程模型可不是Reactor这么简单
    SpringBoot+Mybatis+MySQL实现读写分离
  • 原文地址:https://www.cnblogs.com/gmq-sh/p/5097782.html
Copyright © 2011-2022 走看看