javascript 浮点数计算精度问题的解决方案

// 获取小数位数
function getDecimalCount(num) {
	let count;

	try {
		count = num.toString().split('.')[1].length;
	} catch(e) {
		count = 0;
	}

	return count;
}

// 修复精度问题--加法
function decimalAdd(num1, num2) {
	if (num1 == null || num2 == null) return;

    const max = Math.pow(10, Math.max(getDecimalCount(num1), getDecimalCount(num2)));

    if (getDecimalCount(num1) == getDecimalCount(num2)) {
    	num1 = (num1 + '').replace('.', '');
    	num2 = (num2 + '').replace('.', '');
    } else if (getDecimalCount(num1) > getDecimalCount(num2)) {
    	const fillZero = '0'.repeat(getDecimalCount(num1) - getDecimalCount(num2));
    	num1 = (num1 + '').replace('.', '');
    	num2 = (num2 + '').replace('.', '') + fillZero;
    } else {
    	const fillZero = '0'.repeat(getDecimalCount(num2) - getDecimalCount(num1));
    	num1 = (num1 + '').replace('.', '') + fillZero;
    	num2 = (num2 + '').replace('.', '');
    }

    return (Number(num1) + Number(num2)) / max;    
}

// 修复精度问题--减法
function decimalSub(num1, num2) {
	if (num1 == null || num2 == null) return;

    return decimalAdd(num1, -num2);
}

// 修复精度问题--乘法
function decimalMul(num1, num2) {
	if (num1 == null || num2 == null) return;

	const sum = getDecimalCount(num1) + getDecimalCount(num2);

    return Number((num1 + '').replace('.', '')) * Number((num2 + '').replace('.', '')) / Math.pow(10, sum);
}

// 修复精度问题--除法
function decimalDiv(num1, num2) {
	if (num1 == null || num2 == null) return;

	const count1 = getDecimalCount(num1);
	const count2 = getDecimalCount(num2);

    const formatNum1 = Number((num1 + '').replace('.', ''));
    const formatNum2 = Number((num2 + '').replace('.', ''));

    if (count2 - count1 < 0) {
    	// 由于 Math.pow(10, count2 - count1) 为小数,需要处理精度问题
    	return decimalMul((formatNum1 / formatNum2), Math.pow(10, count2 - count1));
    } else {
    	return (formatNum1 / formatNum2) * Math.pow(10, count2 - count1);
    }
}

1.1 + 1.3 // 2.4000000000000004
decimalAdd(1.1, 1.3) // 2.4

1.3 - 1.1 // 0.19999999999999996
decimalSub(1.3, 1.1) // 0.2

19.9 * 100 // 1989.9999999999998
decimalMul(19.9, 100) // 1990

19.9 / 10 // 1.9899999999999998
decimalDiv(19.9, 10) // 1.99
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值