如何获得 2^k 的数字的 lg2
获取一个数字的以 2 为底的对数的最佳解决方案是什么,我知道这个数字是 2 的幂 (2^k
)。 (当然,我只知道值 2^k
而不是 k
本身。)
我想到的一种方法是减去 1,然后进行位计数:
lg2(n) = bitcount( n - 1 ) = k, iff k is an integer
0b10000 - 1 = 0b01111, bitcount(0b01111) = 4
但是有没有更快的方法(没有缓存)?另外,不涉及位数快的东西也很高兴知道?
其中一个应用程序是:
suppose you have bitmask
0b0110111000
and value
0b0101010101
and you are interested of
(value & bitmask) >> number of zeros in front of bitmask
(0b0101010101 & 0b0110111000) >> 3 = 0b100010
this can be done with
using bitcount
value & bitmask >> bitcount((bitmask - 1) xor bitmask) - 1
or using lg2
value & bitmask >> lg2(((bitmask - 1) xor bitmask) + 1 ) - 2
它比 更快bitcount 没有缓存,它应该比 O(lg(k))
更快,其中 k
是存储位数。
What is the best solution for getting the base 2 logarithm of a number that I know is a power of two (2^k
). (Of course I know only the value 2^k
not k
itself.)
One way I thought of doing is by subtracting 1 and then doing a bitcount:
lg2(n) = bitcount( n - 1 ) = k, iff k is an integer
0b10000 - 1 = 0b01111, bitcount(0b01111) = 4
But is there a faster way of doing it (without caching)? Also something that doesn't involve bitcount about as fast would be nice to know?
One of the applications this is:
suppose you have bitmask
0b0110111000
and value
0b0101010101
and you are interested of
(value & bitmask) >> number of zeros in front of bitmask
(0b0101010101 & 0b0110111000) >> 3 = 0b100010
this can be done with
using bitcount
value & bitmask >> bitcount((bitmask - 1) xor bitmask) - 1
or using lg2
value & bitmask >> lg2(((bitmask - 1) xor bitmask) + 1 ) - 2
For it to be faster than bitcount without caching it should be faster than O(lg(k))
where k
is the count of storage bits.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的。如果您知道所讨论的整数是 2 的幂,则可以在不使用
lg(n)
中的位数的情况下执行此操作。在每个
reg |=
步骤中,我们连续测试x
的任何位是否与arr
中的交替位掩码共享。如果是,则意味着lg(x)
具有该位掩码中的位,并且我们有效地将2^k
添加到reg
,其中 k 是交替位掩码长度的对数。例如,0xFF00FF00 是 8 个 1 和 0 的交替序列,因此此位掩码的k
为 3(或lg(8)
)。本质上,每个
reg |= ((x & arr[k]) ...
步骤(以及初始赋值)测试lg(x)
是否具有位如果是这样 太神奇了,让我们尝试一个例子。假设我们想知道 2,048 是 2 的幂:
我们看到
reg
的最终值为 2^0 + 2^1 + 2^3,这确实是 11。Yes. Here's a way to do it without the bitcount in
lg(n)
, if you know the integer in question is a power of 2.In each of the
reg |=
steps, we successively test to see if any of the bits ofx
are shared with alternating bitmasks inarr
. If they are, that means thatlg(x)
has bits which are in that bitmask, and we effectively add2^k
toreg
, wherek
is the log of the length of the alternating bitmask. For example, 0xFF00FF00 is an alternating sequence of 8 ones and zeroes, sok
is 3 (orlg(8)
) for this bitmask.Essentially, each
reg |= ((x & arr[k]) ...
step (and the initial assignment) tests whetherlg(x)
has bitk
set. If so, we add it toreg
; the sum of all those bits will belg(x)
.That looks like a lot of magic, so let's try an example. Suppose we want to know what power of 2 the value 2,048 is:
We see that the final value of
reg
is 2^0 + 2^1 + 2^3, which is indeed 11.如果您知道该数字是 2 的幂,则可以将其右移 (
>>
),直到它等于 0。右移的次数(减 1)就是您的k
。编辑:比这更快的是查找表方法(虽然你牺牲了一些空间,但不是很多)。请参阅http:// doctorinterview.com/index.html/algorithmscoding/find-the-integer-log-base-2-of-an-integer/。
If you know the number is a power of 2, you could just shift it right (
>>
) until it equals 0. The amount of times you shifted right (minus 1) is yourk
.Edit: faster than this is the lookup table method (though you sacrifice some space, but not a ton). See http://doctorinterview.com/index.html/algorithmscoding/find-the-integer-log-base-2-of-an-integer/.
许多架构都有“查找第一个”指令(bsr、clz、bfffo、cntlzw 等),这比位计数方法快得多。
Many architectures have a "find first one" instruction (bsr, clz, bfffo, cntlzw, etc.) which will be much faster than bit-counting approaches.
如果您不介意处理浮点数,可以使用 log(x) / log(2)。
If you don't mind dealing with floats you can use
log(x) / log(2)
.