最高有效设置位左侧未设置位的数量?
假设 64 位整数 0x000000000000FFFF
表示为
00000000 00000000 00000000 00000000
00000000 00000000 >11111111 11111111
如何找到最高有效设置位(标有 > 的位)左侧未设置位的数量?
Assuming the 64bit integer 0x000000000000FFFF
which would be represented as
00000000 00000000 00000000 00000000
00000000 00000000 >11111111 11111111
How do I find the amount of unset bits to the left of the most significant set bit (the one marked with >) ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
在直接 C 中(在我的设置中,long long 是 64 位),取自类似的 Java 实现:(在阅读更多汉明权重后更新)
更多解释:顶部部分只是将所有位设置在最重要的右侧1,然后否定它。 (即最重要的 1 的“左边”的所有 0 现在都是 1,其他所有都是 0)。
然后我使用 汉明权重 实现来计算位数。
我很想知道这是如何提高效率的。不过,用几个值对其进行了测试,它似乎有效。
In straight C (long long are 64 bit on my setup), taken from similar Java implementations: (updated after a little more reading on Hamming weight)
A little more explanation: The top part just sets all bit to the right of the most significant 1, and then negates it. (i.e. all the 0's to the 'left' of the most significant 1 are now 1's and everything else is 0).
Then I used a Hamming Weight implementation to count the bits.
I'd be curious to see how this was efficiency wise. Tested it with several values though and it seems to work.
基于:http://www.hackersdelight.org/HDcode/nlz.c.txt< /a>
如果您想要一个可以让您省下午餐的版本,就在这里:
正如您将看到的,您可以通过仔细分析汇编器来节省周期,但这里的策略并不是一个可怕的策略一。 while循环将运行Lg[64]=6次;每次它都会将问题转换为计算一半大小的整数的前导位数的问题。
while 循环中的 if 语句提出这样的问题:“我可以用一半的位数表示这个整数吗?”,或者类似地,“如果我把它切成两半,我会失去它吗?”。 if() 有效负载完成后,我们的数字将始终位于最低 n 位。
在最后阶段,v要么是0,要么是1,这就正确地完成了计算。
Based on: http://www.hackersdelight.org/HDcode/nlz.c.txt
If you'd like a version that allows you to keep your lunch down, here you go:
As you'll see, you can save cycles on this by careful analysis of the assembler, but the strategy here is not a terrible one. The while loop will operate Lg[64]=6 times; each time it will convert the problem into one of counting the number of leading bits on an integer of half the size.
The if statement inside the while loop asks the question: "can i represent this integer in half as many bits", or analogously, "if i cut this in half, have i lost it?". After the if() payload completes, our number will always be in the lowest n bits.
At the final stage, v is either 0 or 1, and this completes the calculation correctly.
如果您正在处理无符号整数,您可以这样做:
我不知道它将如何在性能上与已经提供的循环和计数方法进行比较,因为 log2() 可能很昂贵。
编辑:
这可能会导致高值整数出现一些问题,因为
log2()
函数正在转换为double
并且可能会出现一些数字问题。您可以使用与long double
配合使用的log2l()
函数。更好的解决方案是使用整数log2()
函数,如 这个问题。If you are dealing with unsigned integers, you could do this:
I don't know how it will compare in performance to the loop and count methods that have already been offered because log2() could be expensive.
Edit:
This could cause some problems with high-valued integers since the
log2()
function is casting todouble
and some numerical issues may arise. You could use thelog2l()
function that works withlong double
. A better solution would be to use an integerlog2()
function as in this question.其中
count_bits_set
是您能找到的最快的位数计数版本。请参阅https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel< /a> 用于各种位计数技术。Where
count_bits_set
is the fastest version of counting bits you can find. See https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel for various bit counting techniques.我不确定我是否正确理解了这个问题。我认为你有一个 64 位值并且想要找到其中前导零的数量。
一种方法是找到最高有效位并简单地从 63 中减去它的位置(假设最低位是位 0)。您可以通过测试是否在所有 64 位的循环内设置某个位来找出最高有效位。
另一种方法可能是在 gcc 中使用(非标准)
__builtin_clz
。I'm not sure I understood the problem correctly. I think you have a 64bit value and want to find the number of leading zeros in it.
One way would be to find the most significant bit and simply subtract its position from 63 (assuming lowest bit is bit 0). You can find out the most significant bit by testing whether a bit is set from within a loop over all 64 bits.
Another way might be to use the (non-standard)
__builtin_clz
in gcc.我同意二分查找的想法。不过,这里有两点很重要:
以下模板内容可以正确查找任何无符号类型变量的MSB。
I agree with the binary search idea. However two points are important here:
The following template stuff finds the MSB correctly of any unsigned type variable.
就这样,当您需要其他尺寸时,更新起来非常简单......
Here you go, pretty trivial to update as you need for other sizes...
与user470379的想法相同< /a>,但是倒计时...假设所有 64 位均未设置。当值大于 0 时,继续将值右移并减少未设置位的数量:
Same idea as user470379's, but counting down ...Assume all 64 bits are unset. While value is larger than 0 keep shifting the value right and decrementing number of unset bits:
尝试
Try
使用以 2 为底的对数得到最高有效数字 1。
依此类推...
之间的数字成为对数结果的分数。因此,将值转换为 int 会得到最高有效数字。
一旦你得到这个数字,比如 b,简单的 64 - n 就是答案。
Use log base 2 to get you the most significant digit which is 1.
and so on...
The numbers in between become fractions of the log result. So typecasting the value to an int gives you the most significant digit.
Once you get this number, say b, the simple 64 - n will be the answer.