一、toFixed和 Math.round四舍五入
1. toFixed()方法
toFixed() 方法可把 Number 四舍五入为指定小数位数的数字,但其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。具体规则如下:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。
1.55.toFixed(1) //1.6
1.555.toFixed(2) //1.55
2. Math.round()
Math.round() 函数返回一个数字四舍五入后最接近的整数。
如果参数的小数部分大于 0.5,则舍入到相邻的绝对值更大的整数。 如果参数的小数部分小于 0.5,则舍入到相邻的绝对值更小的整数。如果参数的小数部分恰好等于0.5,则舍入到相邻的在正无穷(+∞)方向上的整数。Math.round()并不总是舍入到远离0的方向(尤其是在负数的小数部分恰好等于0.5的情况下)
Math.round(30.49) //30
Math.round(30.5) //31
Math.round(-30.49); //-30
Math.round(-30.5); //-30
Math.round(-30.51); //-31
3. Math.pow(base, exponent)
返回基数(base)的指数(exponent)次幂
Math.pow(4, 0.5) //2
Math.pow(4, 2) //16
4. parseFloat()
函数可解析一个字符串,并返回一个浮点数
parseFloat("9") //9
parseFloat("44 12 33") //44
parseFloat("30 aaaa") //30
parseFloat("word 30") //NaN
二、数字按指定精度四舍五入最终方法
思路:数字(number)乘以10的精度(precision)次幂,再除以10的精度(precision)次幂
function round(number, precision) {
return parseFloat(
Math.round(Number(number) * Math.pow(10, precision)) /
Math.pow(10, precision)
);
}
round(1.555, 2); //1.56
三、js中数字直接计算bug
1、原生js运算结果不一定准确,会丢失精度
console.log(0.1 + 0.2); //0.30000000000000004
console.log(1.99 - 0.9); //1.0899999999999999
console.log(7 * 0.7); //4.8999999999999995
console.log(5.99 / 1000); //0.0059900000000000005
2、原因
数字转换为二进制的过程中丢失了精度
3、解决方案
计算前乘以10的n次方幂,计算后再除以10的n次方幂
四、修复JS中浮点数加减乘除小数点异常bug
1、加法
扩大小数点位数最多的倍数,add方法中使用了修复的乘法计算
function accAdd(a, b) {
var c, d, e;
try {
c = a.toString().split(".")[1].length;
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length;
} catch (f) {
d = 0;
}
return e = Math.pow(10, Math.max(c, d)), (accMul(a, e) + accMul(b, e)) / e;
}
//给Number类型增加一个add方法
Number.prototype.add = function (arg) {
return accAdd(arg, this);
};
Number(1.111).add(2.123); // 3.234
2、减法
accSub方法中使用了修复的乘法计算
function accSub(a, b) {
var c, d, e;
try {
c = a.toString().split(".")[1].length;
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length;
} catch (f) {
d = 0;
}
return e = Math.pow(10, Math.max(c, d)), (accMul(a, e) - accMul(b, e)) / e;
}
Number.prototype.sub= function (arg){
return accSub(arg,this);
}
3、乘法
function accMul(a, b) {
var c = 0,
d = a.toString(),
e = b.toString();
try {
c += d.split(".")[1].length;
} catch (f) {}
try {
c += e.split(".")[1].length;
} catch (f) {}
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
}
// 给Number类型增加一个mul方法,调用起来更加方便。
Number.prototype.mul = function (arg) {
return accMul(arg, this);
};
Number(1.234).mul(2.1); // 2.5914
4、除法
function accDiv(a, b) {
var c, d, e = 0,
f = 0;
try {
e = a.toString().split(".")[1].length;
} catch (g) {}
try {
f = b.toString().split(".")[1].length;
} catch (g) {}
return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), accMul(c / d, Math.pow(10, f - e));
}
//给Number类型增加一个div方法,调用起来更加方便。
Number.prototype.div = function (arg) {
return accDiv(this, arg);
};
Number(2.2).div(1.1) //2
五、js计算插件
Math.js
Numeral.js