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

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

青灯夜游
Release: 2020-06-15 09:57:06
forward
2654 people have browsed it

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))
    }
}
Copy after login

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

比如加法:

268.34.myDiv(0.83);//321.7505995203837
Copy after login

所以还要优化

我重新做了一版:

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;);
}
Copy after login

如果你发现了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!

Related labels:
source:segmentfault.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template