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


声明:本文转载自https://my.oschina.net/yangyishe/blog/1579612,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

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,数字类型 

本文发表于2017年11月25日 10:33
(c)注:本文转载自https://my.oschina.net/yangyishe/blog/1579612,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2383 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1