关于JS小数的加减乘除精度丢失问题

motioliang2021-8-21jsjs

TIP

在 javascript 中,当你使用小数进行加减乘除运算时,你会发现,所得到的结果有时后面带有长长的一段小数,使运算变得复杂,并且影响计算结果。上网查询了一下原因,大致如下:在 javascript 中,带小数的数据运算时总会出现好多位小数.这是因为在 javascript 中浮点数的计算是以 2 进制计算的。

/**
 * @desc 加法运算,避免数据相加小数点后产生多位数和计算精度损失。
 * @param {number} num1 加数1
 * @param {number} num2 加数2
 * @author motioliang
 */
function numAdd(num1, num2) {
    var baseNum, baseNum1, baseNum2, c
    try {
        baseNum1 = num1.toString().split('.')[1].length
    } catch (e) {
        baseNum1 = 0
    }
    try {
        baseNum2 = num2.toString().split('.')[1].length
    } catch (e) {
        baseNum2 = 0
    }
    c = Math.abs(baseNum1 - baseNum2)
    baseNum = Math.pow(10, Math.max(baseNum1, baseNum2))
    if (c > 0) {
        var cm = Math.pow(10, c)
        if (baseNum1 > baseNum2) {
            num1 = Number(num1.toString().replace('.', ''))
            num2 = Number(num2.toString().replace('.', '')) * cm
        } else {
            num1 = Number(num1.toString().replace('.', '')) * cm
            num2 = Number(num2.toString().replace('.', ''))
        }
    } else {
        num1 = Number(num1.toString().replace('.', ''))
        num2 = Number(num2.toString().replace('.', ''))
    }
    return (num1 + num2) / baseNum
}

/**
 * @desc 减法运算,避免数据相减小数点后产生多位数和计算精度损失。
 * @param {number} num1 被减数
 * @param {number} num2 减数
 * @author motioliang
 */
function numSub(num1, num2) {
    var baseNum, baseNum1, baseNum2
    var precision // 精度
    try {
        baseNum1 = num1.toString().split('.')[1].length
    } catch (e) {
        baseNum1 = 0
    }
    try {
        baseNum2 = num2.toString().split('.')[1].length
    } catch (e) {
        baseNum2 = 0
    }
    baseNum = Math.pow(10, Math.max(baseNum1, baseNum2))
    precision = baseNum1 >= baseNum2 ? baseNum1 : baseNum2
    return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision)
}

/**
 * @desc 乘法运算,避免数据相乘小数点后产生多位数和计算精度损失。
 * @param {number} num1 乘数1
 * @param {number} num2 乘数2
 * @author motioliang
 */
function numMulti(num1, num2) {
    var baseNum = 0
    try {
        baseNum += num1.toString().split('.')[1].length
    } catch (e) {}
    try {
        baseNum += num2.toString().split('.')[1].length
    } catch (e) {}
    var baseNum1 = Number(num1.toString().replace('.', ''))
    var baseNum2 = Number(num2.toString().replace('.', ''))
    return (baseNum1 * baseNum2) / Math.pow(10, baseNum)
}

/**
 * @desc 除法运算,避免数据相除小数点后产生多位数和计算精度损失。
 * @param {number} num1 被除数
 * @param {number} num2 除数
 * @author motioliang
 */
function numDiv(num1, num2) {
    var baseNum1 = 0,
        baseNum2 = 0
    try {
        baseNum1 = num1.toString().split('.')[1].length
    } catch (e) {
        baseNum1 = 0
    }
    try {
        baseNum2 = num2.toString().split('.')[1].length
    } catch (e) {
        baseNum2 = 0
    }
    var baseNum3 = Number(num1.toString().replace('.', ''))
    var baseNum4 = Number(num2.toString().replace('.', ''))
    return (baseNum3 / baseNum4) * Math.pow(10, baseNum2 - baseNum1)
}
最后更新时间 2023/6/19 17:39:14