转:如何优雅的获取数值的整数部分

429 阅读1分钟

在处理数值的时候,获取浮点数的整数和小数部分,是一种常见的操作,在JavaScript中有许多方法可以达到目的,但也正因为方法众多,所以哪种方法更好,也值得我们仔细研究一番。

1. parseInt

let num = 3.75;
console.log(parseInt(num)); // 3
num = -3.75;
console.log(parseInt(num)); // -3

parseInt(3.75),会先将3.75转换成字符串"3.75", 然后在转换成3. 这个方法是一个将字符串转换为整数的方法,如果参数不是一个字符串,则将其转换成字符串,性能开销大。 关键还有一个致命的问题:

console.log(parseInt(0.00000001));  // 1
console.log(parseInt(1000000000000000000000)); // 1

分析: 这是因为toString(),0.00000001.toString()===1e-8而1000000000000000000000..toString() === 1e+21。

2. Math.ceil + Math.floor

Math.ceil() 向上取整

Math.floor() 向上取整

function trunc (num) {
    if (num>=0) {
        return Math.floor(num)
    } else {
        return Math.ceil(num)
    }
}
console.log(trunc(3.75));  // 3
console.log(trunc(-3.75)); // -3

使用Math.round和Math.ceil实现trunc方法,要比使用parseInt的性能好,因为省去了转字符串。我们可以用jsperf测一下:

3. Math.trunc()

console.log(Math.trunc(3.75));    // 3
console.log(Math.trunc(-3.75));   // -3

4. |

console.log(3.75 | 0);    // 3
console.log(-3.75 | 0);   // -3

注意: 因为bitwise操作将操作数转为Int32,所以它不能处理超过32位的数值取整,而JavaScript有效整数的范围是53位。

const num = 17179869184.89;
console.log(num | 0); // 0
console.log(Math.trunc(num)); // 17179869184

综上: 所以如果要考虑压缩代码的大小,且明确知道数值范围不会超过32位整数的时候,可以考虑使用 | 0取整。否则,还是使用Math方法吧。

附: 性能测试 jsperf.com