Heim > Web-Frontend > js-Tutorial > Wie kann das Problem des Präzisionsverlusts bei numerischen Javascript-Berechnungen gelöst werden?

Wie kann das Problem des Präzisionsverlusts bei numerischen Javascript-Berechnungen gelöst werden?

青灯夜游
Freigeben: 2020-06-15 09:57:06
nach vorne
2678 Leute haben es durchsucht

Wie kann das Problem des Präzisionsverlusts bei numerischen Javascript-Berechnungen gelöst werden?

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))
    }
}
Nach dem Login kopieren

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

比如加法:

268.34.myDiv(0.83);//321.7505995203837
Nach dem Login kopieren

所以还要优化

我重新做了一版:

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;);
}
Nach dem Login kopieren

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

推荐教程:《JS教程

Das obige ist der detaillierte Inhalt vonWie kann das Problem des Präzisionsverlusts bei numerischen Javascript-Berechnungen gelöst werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Aktuelle Ausgaben
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage