11

Causes of floating point precision loss

Since the bottom layer of the computer is implemented in binary, some numbers cannot be displayed in full. Just like some irrational numbers cannot be fully displayed, such as pi 3.1415926..., 0.3333... etc. JavaScript follows the IEEE754 specification and uses double precision storage (double precision), occupying 64 bits.

1 bit is used to represent the sign bit, 11 bits are used to represent the exponent, and 52 bits are used to represent the mantissa.

Because at the lowest level of the computer, numerical operations and operations are implemented in binary, so the computer has no way to accurately represent floating-point numbers, but can only use binary approximate equal to represent the fractional part of floating-point numbers.

Some typical scenarios where numerical precision is lost

//addition
0.1 + 0.2 = 0.30000000000000004
0.7 + 0.1 = 0.7999999999999999

//subtract
1.5 - 1.2 = 0.30000000000000004
0.3 - 0.2 = 0.09999999999999998

//multiplication
1.1 * 100 = 110.00000000000001
0.8 * 3 = 2.4000000000000004

//division
0.3 / 0.1 = 2.9999999999999996
0.69 / 10 = 0.06899999999999999

solution

Third Party Libraries:

Decimal.js
bignumber.js
big.js

Handwritten code:

//addition

 function plus(num1, num2) {
    let r1, r2, m;
    try {
        r1 = num1.toString().split(".")[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = num2.toString().split(".")[1].length
    } catch (e) {
        r2 = 0
    }
    m = Math.pow(10, Math.max(r1, r2))
    return (num1 * m + num2 * m) / m
}

//subtract

 function subtract(num1, num2) {
    let r1, r2, m, n;
    try {
        r1 = num1.toString().split(".")[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = num2.toString().split(".")[1].length
    } catch (e) {
        r2 = 0
    }
    m = Math.pow(10, Math.max(r1, r2));
    n = (r1 >= r2) ? r1 : r2;
    return ((num1 * m - num2 * m) / m).toFixed(n);
}

//multiplication

 function multiply(num1, num2) {
    let m = 0,
        s1 = num1.toString(),
        s2 = num2.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)
 }

//division

 function divide(num1, num2) {
    let t1 = 0,
        t2 = 0,
        r1, r2;
    try {
        t1 = num1.toString().split(".")[1].length
    } catch (e) {}
    try {
        t2 = num2.toString().split(".")[1].length
    } catch (e) {}
    with(Math) {
        r1 = Number(num1.toString().replace(".", ""))
        r2 = Number(num2.toString().replace(".", ""))
        return multiply((r1 / r2), pow(10, t2 - t1));// multiply乘法配合一起使用
    }
}

After reading N articles about precision loss, this article was written with reference to many other bloggers' articles.


沉静地闪光
11.2k 声望3.1k 粉丝

值得做的事情,值得现在就去做并一直坚持做;