javascript浮点数运算修正

众所周知,javascript对于浮点数的运算一直都是有问题的,比如0.2+0.1 结果是 0.30000000000000004。

下面是我的解决方案,先贴代码了:

var calMath = (function() {
    var isFloat = function(a) { 
        var reg = /d.d+/g
        return reg.test(a)
    }
    var getFloatDigit = function(a) { 
        var digit, len
        a = a.toString()
        digit = a.split(".")
        len = digit[1] == undefined ? 0 : digit[1].length
        return len
    }
    var allArithmetic = function(type, a, b) { 
        var c, gfd_a, gfd_b, baseLen, baseMulti
        var a = Number(a),
            b = Number(b)
        if (isFloat(a) || isFloat(b)) {
            gfd_a = getFloatDigit(a)
            gfd_b = getFloatDigit(b)
            baseLen = gfd_a >= gfd_b ? gfd_a : gfd_b
            baseMulti = Math.pow(10, baseLen)
            a = type != "add" ? Number(a.toString().replace(".", "")) : a
            b = type != "add" ? Number(b.toString().replace(".", "")) : b
            if (type == "add") {
                c = ((a * baseMulti + b * baseMulti) / baseMulti).toFixed(baseLen)
            } else if (type == "multi") {
                c = (a * b) / Math.pow(10, gfd_a + gfd_b)
            } else if (type == "divi") {
                c = ((a / b) * Math.pow(10, gfd_b - gfd_a))
            }
        } else {
            if (type == "add") {
                c = a + b
            } else if (type == "multi") {
                c = a * b
            } else if (type == "divi") {
                c = a / b
            }
        }
        return c
    }
    return {
        add: function(a, b) {
            return allArithmetic("add", a, b)
        },
        sub: function(a, b) {
            return allArithmetic("add", a, -b)
        },
        multi: function(a, b) {
            return allArithmetic("multi", a, b)
        },
        divi: function(a, b) {
            return allArithmetic("divi", a, b)
        }
    }
})()

思路就是:

1. 判定是否是浮点数。

2. 如果不是浮点数,就选择常规的运算方法。

3. 如果是浮点数,则先取浮点数后面个数(即小数点的位数)。

4. 如果是浮点数的加减法运算,则比较他们小数点后的位数,取较大的那个,暂且称之为n,这个数有什么用呢?就是先让我们的浮点数都变成整数(小数乘以10的n次方),然后在重新变成浮点数(结果再除以10的n次方),整数做加减法总没事了吧?其实并不一定,有些情况,浮点数乘以10的次方时,出来的数也会有“尾巴”,但是这个“尾巴”的误差相对来说比较小,所以我们利用toFixed(n)来处理掉它就ok了。

5. 如果是浮点数的乘法运算,其实思路跟上面的类似,先将他们小数点后的位数相加,取得的值继续叫他小n吧,小n暂且不管他,我们这里换种让浮点数变成整数的方式,就是直接把小数点给去掉,理由就是刚刚在加减法时提到的,如果用10的n次方让小数变整数,其实有可能出现误差很小的浮点数的,那在加减法中我们可以有补救措施,但是在乘法中,一个点0.00000000x的小数出现了之后,再补救就不可能了。那我们这里的小n有什么用呢,当然是把整数再变回小数啦。

6. 如果是浮点数的除法运算,思路跟乘法基本一致,看着代码自己思考吧。

console.log(calMath.add(0.2,0.1)) //结果是0.3哦

原文地址:https://www.cnblogs.com/junhua/p/4356458.html