js中浮点数加减法异常(字符拼接,误差)的解决策略

本文针对JavaScript中常见的变量加减法异常问题,提出一种利用封装函数实现高精度加减运算的方法。通过调整变量精度并结合四舍五入策略,确保了计算结果的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.变量加减法常见异常

在写html中的js时,进行变量的加减法经常会遇到的两种异常问题(表格中还包含了一般解决策略):

常见异常举例原因一般解决策略
变量相加按照字符串方式相加10+10=1010系统在加减时有时默认将变量识别为字符串类型,而非数字类型parseFloat();<br>parseInt();<br>在变量运算第一步执行减零操作,如var sum=a-0+b;
浮点数加减的结果有误差1.63-0.63=0.99999732<br>(只是举个例子,真实的结果可能并非如此)浮点数设计误差的存在(任何系统的浮点数都无法避免该弊端)parseInt();<br>toFixed();<br>Math.round();

2.一般解决策略可能存在的小问题

但是实际使用的过程中,会发现上述的一般解决策略在使用时,多多少少会遇到一些问题,尤其是将两种异常放在一起的时候,都不是那么完美:

  1. parseFloat(): 将任意可识别的变量转化为数字类型,方法本身没有什么问题,但在加减法的过程中,往往会出现第二种异常,需要其他方法的协同.
  2. parseInt(): 将任意可识别的变量转化为整数的数字类型,与parseFloat()相似,但==不建议使用==,因为在分析非整型的变量时会默认使用去尾法,考虑到第二种异常的存在,即使计算中的所有变量都是整数,最后可能也不能得到准确的值.
  3. 变量运算第一步执行减零操作: 这种策略我使用的较少,唯一一次使用的时候正好碰到了多个变量的加减法,发现还是出现了第一种异常,所以个人是==不太推荐==的.
  4. toFixed(): 该函数的本义是将数字类型转化为理想位数的字符串,在使用上有两个限制,一是执行变量必须确保是数字类型,否则会报错;二是它转化为字符串类型的数字显示时,并不完全是按照四舍五入的规则进行的.这点用toFixed()比较多的人应该深有感触,当执行变量的舍入首位为5时,该函数会进行各种各样奇怪的舍入,好在当舍入首位非5的情况下,还是严格按照四舍五入规则的.
  5. Math.round(): 标准的四舍五入方法,如果硬要说缺点,那就是只能将数字四舍五入到整数上,这确实是个限制.

3.简单而严谨的实现变量加减法--封装函数

通过第二部分我们得知目前常用的解决策略,多多少少都一些缺点或不足,似乎没有一个非常严谨而又简单的方法来实现加减法.
基于此,我写了一个封装函数来实现这个功能:
(由于没有很好的浮点数的四舍五入方法,此处使用的是先将所有变量乘以10^n^,变为整数再进行加减操作,最后除以10^n^)

/**
 * 数据处理-准确(准确程度视位数而定)的加减法
 * @param arrNum 加减数的数组
 * @param isNum	(选填)返回结果是否为数字,默认返回字符串
 * @param digits (选填)精确位数,默认为2位
 * @returns
 */
function sum_pack(arrNum,isNum,digits){
	digits=digits||2;
	isNum=isNum||false;
	var multi=Math.pow(10,digits);
	var intSum=0;
	for(var i in arrNum){
		var num=arrNum[i];
	    if(num!=''&&!isNaN(num)){
	    	var fltNum=parseFloat(num);
	    	//此处也可考虑将四舍五入放在加减后进行,视业务需求而定
	    	var intNum=Math.round(fltNum*multi);
	    	intSum+=intNum;
	    }else if(isNaN(num)){
	    	console.log('can not parse : '+num);
	    }
	}
	var fltSum=intSum/multi;
	if(isNum){
		return fltSum;
	}else{
	    return fltSum.toFixed(digits);
	}
}

用法参考如下:

var s='5.678';
var arrNum=[1,'2.3',-4,-s];//-s在js中会自动取相反数,负数亦然
var sum1=sum_pack(arrNum);
var sum2=sum_pack(arrNum,true);
var sum3=sum_pack(arrNum,true,3);
console.log(sum1);//print:-6.4,字符串类型
console.log(sum2);//print:-6.4,数字类型
console.log(sum3);//print:-6.38,数字类型

转载于:https://my.oschina.net/yangyishe/blog/1579612

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值