Home  >  Article  >  Web Front-end  >  How to solve the problem of losing precision in javascript numerical calculations?

How to solve the problem of losing precision in javascript numerical calculations?

青灯夜游
青灯夜游forward
2020-06-15 09:57:062572browse

How to solve the problem of losing precision in javascript numerical calculations?

js数字计算丢失精度问题解决方案

计算机世界里,数字的计算,所有语言都会丢失精度,所以没有万全之策,但在人力范围内,尽量解决。

网上找了一部分代码,发现是有问题的,比如:

//加法 
Number.prototype.myAdd = function(arg2) {
    var arg1 = this;
    if (isNaN(arg2)) {
        return 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.prototype.mySub = function(arg2) {
    var arg1 = this;
    if (isNaN(arg2)) {
        return 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 ((arg1 * m - arg2 * m) / m).toFixed(n);
}
//乘法 
Number.prototype.myMul = function(arg2) {
    var arg1 = this;
    if (isNaN(arg2)) {
        return 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.prototype.myDiv = function(arg2) {
    var arg1 = this;
    if (isNaN(arg2)) {
        return 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).myMul(pow(10, t2 - t1))
    }
}

在计算一些特殊的数字时,仍然有问题:

比如加法:

268.34.myDiv(0.83);//321.7505995203837

所以还要优化

我重新做了一版:

var operationNumber = function (arg1,arg2,operator) {
    var oper=['+','-','*','/'];
    // 不合法的运算
    if (isNaN(arg1)||isNaN(arg2)||oper.indexOf(operator)<0) {
        return NaN;
    }
    // 除以0
    if (operator===&#39;/&#39;&&Number(arg2)===0) {
        return Infinity;
    }
    // 和0相乘
    if (operator===&#39;*&#39;&&Number(arg2)===0) {
        return 0;
    }
    // 相等两个数字相减
    if ((arg1===arg2||Number(arg1)===Number(arg2))&&operator===&#39;-&#39;) {
        return 0;
    }
    var r1, r2, max,_r1,_r2;
    try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 }
    try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 }
    max = Math.max(r1, r2)
    _r1 = max-r1;
    _r2 = max-r2;
    if (_r1!==0) {
        arg1=arg1+&#39;0&#39;.repeat(_r1)
    }
    if (_r2!==0) {
        arg2=arg2+&#39;0&#39;.repeat(_r2)
    }
    arg1 = Number(arg1.toString().replace(&#39;.&#39;,&#39;&#39;))
    arg2 = Number(arg2.toString().replace(&#39;.&#39;,&#39;&#39;))
    var r3 = operator===&#39;*&#39;?(max*2):(operator===&#39;/&#39;?0:max);
    var newNum = eval(arg1+operator+arg2);
    if (r3!==0) {
        var nStr = newNum.toString();
        nStr = nStr.replace(/^-/,&#39;&#39;);
        if (nStr.length<r3+1) {
            nStr = &#39;0&#39;.repeat(r3+1-nStr.length)+nStr;
        }
        nStr = nStr.replace(new RegExp(&#39;(\\\d{&#39;+r3+&#39;})$&#39;),&#39;.$1&#39;);
        if (newNum<0) {
            nStr = &#39;-&#39;+nStr;
        }
        newNum = nStr*1;
    }
    return newNum;
}
//加法 
Number.prototype.myAdd = function(arg2) {
    return operationNumber(this,arg2,&#39;+&#39;);
}
//减法 
Number.prototype.mySub = function(arg2) {
    return operationNumber(this,arg2,&#39;-&#39;);
}
//乘法 
Number.prototype.myMul = function(arg2) {
    return operationNumber(this,arg2,&#39;*&#39;);
}
// 除法
Number.prototype.myDiv = function(arg2) {
    return operationNumber(this,arg2,&#39;/&#39;);
}

如果你发现了bug,评论区及时反馈,我及时跟进修复

推荐教程:《JS教程

The above is the detailed content of How to solve the problem of losing precision in javascript numerical calculations?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete