如何解决如何在不使用JavaScript中的Math.log的情况下获得指数“ x”2等于“ x”的幂?
到目前为止,我已经掌握了这一切(都是按位的,没有使用Math
函数):
function nextPowerOf2(n) {
if (n && !(n & (n - 1))) {
return n
}
let p = 1
while (p < n) {
p <<= 1
}
return p
}
但是要获得指数,我必须这样做:
const exp = Math.log2(nextPowerOf2(val))
在没有Math.log
的情况下,有没有其他方法可以使用更多原始操作?哪种方法效果更好?
解决方法
我们可以计算一个数字中的位数-将为log2(nextPowerOf2):
const log2ofNextPowerOf2 = (x) => {
if (!x) return 0;
let c = 0,b = 0;
while (x > 0) {
c++; b += x & 1;
x = x >> 1;
}
return b == 1 ? c - 1 : c;
}
// test it:
[0,1,2,3,4,5,8,100].forEach(n => console.log(n,'=>',log2ofNextPowerOf2(n)));
将此与您的原始功能进行比较:
function nextPowerOf2(n) {
if (n && !(n & (n - 1))) {
return n
}
let p = 1
while (p < n) {
p <<= 1
}
return p
}
// test it:
[0,Math.log2(nextPowerOf2(n))));
,
以我的经验,Math.log2的性能非常好,特别是与使用按位甚至查找表的其他选项相比时。
如果您想了解如何按位完成此操作,那么这里有大量资源:http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
以下是一个适用于C ++的JS的示例(请注意Number.MAX_SAFE_INTEGER
之后的数字),速度慢了约59%
function log2(v) {
let b = [0x2,0xC,0xF0,0xFF00,0xFFFF0000,0xFFFFFFFF00000000];
let S = [1,16,32];
let i;
let r = 0;
for (i = 5; i >= 0; i--){
if (v & b[i]) {
v >>= S[i];
r |= S[i];
}
}
return r;
}
log2(nextPowerOf2(348209348));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。