处理小数点精度的问题以及多个数字含小数的相加减乘除

0 阅读2分钟

众所周知,在js中,0.1+0.2 != 0.3,所以当涉及小数的运算时,就需要进行额外处理,基本逻辑就是将所有小数都变成整数进行运算,运算结束后再变回小数。另外,常规的处理都是两数的相加减乘除,但是有时候,比如成本合计,可能是需要还几个数相加,亦或者如经费剩余,总经费可能要减去好几个已使用的经费,等等情况,并非简单两数的想加减乘除,那么调N次方法,个人觉得并不合适。因此自己写了个多个数字的相加减乘除并处理小数精度的方法,水平菜鸡,若有大佬有更好的方法,欢迎指教!

// 随机打一些数字,测试使用
const nums = [0.2688, 3.3656666, 2.55, 9.5656, 11.55555]

多数相加减乘除并处理小数精度问题

1、计算放大倍数

const operatorNumberPoint = (numbers: number[], operator: "+" | "-" | "*" | "/") => {
    let result // 将要返回的结果
    let step // 步长,即放大倍数
    try { // 即使使用了ts,也务必加上try catch,因为你不知道掉方法的人究竟是不是“人”
        step = 10 ** Math.max(...numbers.map(num => {
            return num.toString().split(".")[1] ? num.toString().split(".")[1].length : 0
        }))
        console.log(step) // 10000000
    }
}

image.png

2、获取放大后的数字

const operatorNumberPoint = (numbers: number[], operator: "+" | "-" | "*" | "/") => {
    let result // 将要返回的结果
    let step // 步长,即放大倍数
    try { // 即使使用了ts,也务必加上try catch,因为你不知道掉方法的人究竟是不是“人”
        step = 10 ** Math.max(...numbers.map(num => {
            return num.toString().split(".")[1] ? num.toString().split(".")[1].length : 0
        }))
        console.log(step) // 10000000
        
        const factorNum = numbers.map(num => Number((num * step).toFixed()))
        console.log(factorNum) // [2688000, 33656666, 25500000, 95656000, 115555500]
    }
}

image.png

3、完整加减乘除运算

const operatorNumberPoint = (numbers: number[], operator: "+" | "-" | "*" | "/") => {
    let result // 将要返回的结果
    let step // 步长,即放大倍数
    try { // 即使使用了ts,也务必加上try catch,因为你不知道掉方法的人究竟是不是“人”
        step = 10 ** Math.max(...numbers.map(num => {
            return num.toString().split(".")[1] ? num.toString().split(".")[1].length : 0
        }))
        console.log(step) // 10000000
        
        const factorNum = numbers.map(num => Number((num * step).toFixed()))
        console.log(factorNum) // [2688000, 33656666, 25500000, 95656000, 115555500]
        
        switch (operator) {
            case "+":
                result = factorNum.reduce((lastResult, currentNum) => lastResult + currentNum) / step
                break
            case "-":
                result = factorNum.reduce((lastResult, currentNum) => lastResult - currentNum) / step
                break
            case "*":
                result = factorNum.reduce((lastResult, currentNum) => (lastResult * currentNum) / step) / step
                break
            case "/":
                result = factorNum.reduce((lastResult, currentNum) => (lastResult / currentNum) * step) / step
                break
            default: // 防“非人哉”
                console.error("运算符错误")
                return NaN
        }
    } catch (err) {
        console.error("运算错误:", err)
        return NaN
    }
    return result
}
3.1、加减法运算解析

image.png

计算结果验证:

image.png

减法运算同理:

计算结果验证:

image.png

3.2、乘法运算解析

image.png

计算结果验证:

image.png

3.3、除法运算解析

image.png

计算结果验证:

image.png