js floating point calculation accuracy problem and solution

In javaScript, because floating-point numbers are not precise values, unexpected results often occur when performing floating-point operations.

Consider the following example:

0.1 + 0.2 === 0.3
// 结果返回 false

(0.3 - 0.2) === (0.2 - 0.1)
// 结果返回 false

So be especially careful when calculating decimals, as it needs to be processed to return the expected result.

So, is there any way to solve it?

Not much nonsense, just go to the code. Knock on the blackboard and draw the key points!

class Precision {

    // 加法
    add(a, b) {
        let arr = this.core(a, b);
        return (arr[0] + arr[1]) / arr[2];
    }

    // 减法
    sub(a, b) {
        let arr = this.core(a, b);
        return (arr[0] - arr[1]) / arr[2]; 
    }

    // 乘法
    mul(a, b) {
        let arr = this.core(a, b);
        return arr[0] * arr[1] / Math.pow(arr[2],2);
    }

    // 除法
    div(a, b) {
        let arr = this.core(a, b);
        return arr[0] / arr[1];
    }

    // 核心代码
    core(a, b) {
        a = Number(a).toString();
        b = Number(b).toString();
        let a_pos = a.indexOf('.');
        let b_pos = b.indexOf('.');
        if(a_pos === -1 && b_pos === -1) {
            return [Number(a), Number(b), 1];
        } else {
            let [aPos, bPos] = [0, 0];
            if(a_pos !== -1) {
                aPos = a.length - (a_pos+1);
                a = a.replace('.', '');
            }
            if(b_pos !== -1) {
                bPos = b.length - (b_pos+1);
                b = b.replace('.', '');
            }
            if(aPos < bPos) {
                a += '0'.repeat(bPos - aPos);
            } else {
                b += '0'.repeat(aPos - bPos);
            }
            return [Number(a), Number(b), Math.pow(10, (aPos > bPos ? aPos : bPos))];
        }
    }
}

The idea is actually to convert floating-point numbers to integers first, and then perform operations. For specific methods, please see the core method in the Precision class.

Test code

let Compute = new Precision();  // 实例化Precision类

// 加法
var a = 0.1;
var b = 0.2;
console.log('直接加法运算 a + b =', a + b);
console.log('Precision.js加法运算 a + b =', Compute.add(a, b));

// 减法
var a = 1.0;
var b = 0.7;
console.log('直接减法运算 a - b =', a - b);
console.log('Precision.js减法运算 a - b =', Compute.sub(a, b));

// 乘法
var a = 1.01;
var b = 1.003;
console.log('直接乘法运算 a * b =', a * b);
console.log('Precision.js乘法运算 a * b =', Compute.mul(a, b));

// 除法
var a = 0.029;
var b = 10;
console.log('直接除法运算 a / b =', a / b);
console.log('Precision.js除法运算 a / b =', Compute.div(a, b));

operation result

Description

When the input parameter is not a numeric value and cannot be converted into a numeric value, the calculation result returns NaN

Guess you like

Origin blog.csdn.net/qczxl520/article/details/107974315