指定精度的四舍五入问题

指定精度的四舍五入问题,一直都比较麻烦,没有一个万能的统一的处理,如:
1、Math.round() 函数,它的算法为Math.floor(x+0.5) ,floor 返回不大于的最大整数,求指定精度时:(Math.round(a_Num * Math.pow(10,a_Bit)) /Math.pow(10,a_Bit)) 所以

Round(516889.3*370.55,2) = 191533330.12
Round(-516889.3*370.55,2) = -191533330.11

516889.3*370.55 = 191533330.115;

Math.round(19153333011.5) = 19153333012 ;
//19153333011.5 + 0.5 = 19153333012,floor(19153333012)= 19153333012
Math.round(-19153333011.5) = -19153333011 ;
//-19153333011.5 + 0.5 = -19153333011 ,
floor(-19153333011)= 19153333011

从而导致 A*B !=-(-A*B) 现象。

2、NumberObject.toFixed(num),定义和用法: toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。
经过测试 NumberObject.toFixed(num),则为:
new Number(191533330.115).toFixed(2) = "191533330.12"
new Number(-191533330.115).toFixed(2)  = "-191533330.12"

toFixed大部分能支持,但也不是完全支持,比如:new Number(0.009).toFixed(2) = "0.00" ,0.0056.toFixed(2) = "0.00"

一般就是上面两种实现了,但出现那种某几个数的问题时,我们一时也没有想清楚为什么这样,可能跟计算机的二进制存储有关系,如8.655 * 100 != 865.5 而是865.4999999999999。

其实在我们看来,指定精度的四舍五入也没这么麻烦,就是两点:
1、当指定精度a_Bit大于数字本身的精度o_Bit,我们直接返回,后面补够0
2、当a_Bit < o_Bit 时,我们就要截取了,就看指定精度后一位是否大于等于5,是的话就进位

下面就是用这种思路写的一个,算法比较简单,性能可能不太好,但保正确,
注:这里没有处理补0的操作。
/**
 * 指定精度的四舍五入函数
 * @param a_Num
 * @param a_Bit
 * @return
 */
function Round(a_Num,a_Bit){
	a_Bit = parseInt(a_Bit)
	var tempNum = 0,isNegative = a_Num < 0;
    var thisStr = a_Num + "";
    var start = thisStr.indexOf(".");
    //获取旧的精度,如果没有精度或小于要转化的精度,则直接返回原值
    var oldScale = thisStr.length - start - 1;
    if (start == -1 || oldScale <= a_Bit) {
		return a_Num;
    }
    //截取小数点后,scale之后的数字,判断是否大于5,如果大于5这入为1
	 if(thisStr.substr(start + a_Bit + 1,1) >= 5) {
		 tempNum = 1;
    }
    //计算10的scale次方,把原数字扩大它要保留的小数位数的倍数
  	var temp = Math.pow(10,a_Bit);
  	//截取指定长度的数字,加上进位
    var s = Math.abs(thisStr.substring(0,start+a_Bit+1).replace('.','')) +  tempNum;
    var result = s/temp;
    if (isNegative) {
    	result = -result;
    }
    return result;
}
function test(){
	var a = Round(191533330.115,2);//191533330.12
	var b = Round(-191533330.115,2);//-191533330.12
	var c = Round(19153333011,2);//19153333011
	var d = Round(8.655,2);//8.66
	var e = Round(0.009,2);//0.01
	var g = Round(19153333011.995,2);//19153333012
	
}

你可能感兴趣的:(JavaScript)