计算 32 次方对数的最快方法是啥?

Posted

技术标签:

【中文标题】计算 32 次方对数的最快方法是啥?【英文标题】:What's the fastest way to calculate log of a power of 32?计算 32 次方对数的最快方法是什么? 【发布时间】:2017-04-19 20:10:10 【问题描述】:

鉴于语言是 javascript,并且输入是 < 1073741824,那么获得等价物的最快方法是什么:

Math.floor(Math.log(len) / Math.log(32))

我已经尝试过 if:

if (len < 1024) return 1;
if (len < 32768) return 2;
if (len < 1048576) return 3;
if (len < 33554432) return 4;
if (len < 1073741824) return 5;

并使用位运算符:

// 0000000000000000000000000100000 // 32
// 0000000000000000000010000000000 // 1024
// 0000000000000001000000000000000 // 32768
// 0000000000100000000000000000000 // 1048576
// 0000010000000000000000000000000 // 33554432
// 1000000000000000000000000000000 // 1073741824
function log32(len) 
    return (
        0 + 
        !!(len >>> 30) + 
        !!(len >>> 25) + 
        !!(len >>> 20) + 
        !!(len >>> 15) + 
        !!(len >>> 10) +
        !!(len >>> 5
    )

有没有办法做到这一点更清洁或更少的操作? (性能测量:https://jsperf.com/log32-perf/)

【问题讨论】:

bit twiddling hack 呢? 您认为您的if 级联方法有什么问题?我无法想象一种更快的方式,或者一种更少操作的方式,即使它看起来很老套或在数学上不优雅。 (顺便说一句,考虑到您的初始假设,即输入始终小于 1073741824,您甚至不需要最终的比较操作,if 有条件——只需 return 5; 即可。) 【参考方案1】:

我会选择非常有效的Math.clz32 方法,它返回数字的 32 位二进制表示中前导零位的数量。

const log32 = x => Math.floor((31 - Math.clz32(x))/5);

console.log(log32(1023)); // 1
console.log(log32(1024)); // 2

这将为 32 位范围内的任何 x > 0 返回正确的值。

【讨论】:

不错的 +one;优于 log2()。顺便说一句,您可以将/5 替换为*0.2,这通常更快。 令人印象深刻的 +1。如果我们用 Math.floor 换取结果 | 0 我们可以再刮一根头发,然后比我的 if 测量得更快 在 FF 中,*0.2|0 都没有得到任何显着改善:这两种解决方案在大约 50% 的时间里最快。

以上是关于计算 32 次方对数的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

计算用户平均速度的最快方法是啥?

用二维窗口计算滚动函数的最快方法是啥?

计算大点积的最快方法是啥?

计算行列式的最快方法是啥?

计算R中前两个主成分的最快方法是啥?

计算混合实复矩阵向量积的最快方法是啥?