1.变量加减法常见异常

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

常见异常

举例

原因

一般解决策略

变量相加按照字符串方式相加

10+10=1010

系统在加减时有时默认将变量识别为字符串类型,而非数字类型

parseFloat();
parseInt();
在变量运算第一步执行减零操作,如var sum=a-0+b;浮点数加减的结果有误差
1.63-0.63=0.99999732
(只是举个例子,真实的结果可能并非如此)浮点数设计误差的存在(任何系统的浮点数都无法避免该弊端)
parseInt();
toFixed();
Math.round();

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

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

parseFloat(): 将任意可识别的变量转化为数字类型,方法本身没有什么问题,但在加减法的过程中,往往会出现第二种异常,需要其他方法的协同.

parseInt(): 将任意可识别的变量转化为整数的数字类型,与parseFloat()相似,但==不建议使用==,因为在分析非整型的变量时会默认使用去尾法,考虑到第二种异常的存在,即使计算中的所有变量都是整数,最后可能也不能得到准确的值.

变量运算第一步执行减零操作: 这种策略我使用的较少,唯一一次使用的时候正好碰到了多个变量的加减法,发现还是出现了第一种异常,所以个人是==不太推荐==的.

toFixed(): 该函数的本义是将数字类型转化为理想位数的字符串,在使用上有两个限制,一是执行变量必须确保是数字类型,否则会报错;二是它转化为字符串类型的数字显示时,并不完全是按照四舍五入的规则进行的.这点用toFixed()比较多的人应该深有感触,当执行变量的舍入首位为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,数字类型