_.round(number, [precision=0])
根据 precision(精度) 四舍五入 number。
参数
number(number) : 要四舍五入的数字。[precision=0](number) : 四舍五入的精度。
返回
(number) : 返回四舍五入的数字。
例子
_.round(4.006);
// => 4
_.round(4.006, 2);
// => 4.01
_.round(4060, -2);
// => 4100
在一次bug中发现Math.toFixed的问题
chrome 上的测试结果:
1.35.toFixed(1); // 1.4 正确
1.335.toFixed(2); // 1.33 错误
1.3335.toFixed(3); // 1.333 错误
1.33335.toFixed(4); // 1.3334 正确
1.333335.toFixed(5); // 1.33333 错误
1.3333335.toFixed(6); // 1.333333 错误
对于5这个东西,跟日常的数字四舍五入不一致
常见修复方法
function round(number, precision) {
return Math.round(number * Math.pow(10, precision)) / Math.pow(10, precision)
}
lodash源码
const round = createRound('round')
/**
* Creates a function like `round`.
*
* @private
* @param {string} methodName The name of the `Math` method to use when rounding.
* @returns {Function} Returns the new round function.
*/
function createRound(methodName) {
// Math.round
const func = Math[methodName]
return (number, precision) => {
// 精度 -292 到 292 默认为0
precision = precision == null ? 0 : (precision >= 0 ? Math.min(precision, 292) : Math.max(precision, -292))
if (precision) {
// 这里的逻辑就是Math.round(number * Math.pow(10, precision)) / Math.pow(10, precision)
let pair = `${number}e`.split('e')
const value = func(`${pair[0]}e${+pair[1] + precision}`)
pair = `${value}e`.split('e')
return +`${pair[0]}e${+pair[1] - precision}`
}
return func(number)
}
}
export default createRound
最后
292 最大精度啥回事???
IEEE754 双精度规范 使用8个字节(64位进行存储),结构如下
- 符号位 Sign(S) : 1bit (b63)
- 指数部分Exponent(E) : 11bit (b62-b52)
- 尾数部分Mantissa(M) : 52bit (b51-b0)
- 表达式 -1^S * 2^E * 1.M ————————————————
1. 符号位说明
0为正数 1为负数
2. 部分指数理解
指数部分二进制值范围位0 ~ 2047(2^11-1),但这个取值范围并不能直接使用,需要减去一个偏移1023(2^10-1)(除了最高位其他全为1的时)。所以E的取值范围应该为-1022~1023,为啥不是-1023~1024呢?因为规定-1023和1024为特殊情况使用。
3. 尾数部分理解
尾数部分对应小数部分,占52bit。 0.11为2^E-2 + 2^-4。 小数部分最大取值为(1-2^-52)。
————————————————
这里就要引出js的几个常量
1. 最大值 Number.MAX_VALUE
指数部分和小数部分都取最大值时代入表达式:2^1023*(1+(1-2^-52))。
2. 最小值Number.MIN_VALUE
注意Number.MIN_VALUE时表示的正数最小值,而不是最小值。最小值应为-2^1023*(1+(1-2^-52))
3. 精度Number.EPSILON
两个数的最小差值即尾数部分最后一位是1其他全为0:2^-52。
4. 安全整数
Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER
需要安全表示,则需要保证精确,必须保证这个数转为的2进制必须在尾数部分中,不能四舍五入。一共有52位尾数能表示的整数是2^53-1,那么最大安全整数:2^53-1 最小则为:-(2^53-1)
console.log(Number.MAX_VALUE/Number.MAX_SAFE_INTEGER) 1.99584030953472e+292