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更多的作用不在于此

 

posted @ 2016-01-04 08:53  园芳宝贝  阅读(2080)  评论(0编辑  收藏  举报