获得前导1位的数量

时间:2011-01-17 12:37:01

标签: c# c++ algorithm delphi bit-manipulation

给定无符号数,获得前导1位数的好方法(最好是快速方法)是什么?

我需要这个来计算四点IPv4网络掩码中的CIDR编号。

注意:我看过getting-the-number-of-trailing-1-bits,所以我可以进行基于表格的查找。

注意2:尽管我添加了几个语言标签,但对我来说这是关于算法的,所以如果你有另一种语言的好标签,请随时发帖。

endian-ness

修改

我刚刚发现INET_ADDR functionIN_ADDR structure以big-endian形式存储IPv4地址,而x86是little-endian,我使用的大部分处理器都是little-endian 。
因此,针对这种特定情况的查找表足够快 但是感谢其他答案:在更常见的情况下,它们的效果非常好。

- 的Jeroen

4 个答案:

答案 0 :(得分:9)

如果反转所有位,可以使用前导检测算法(相当于log2算法);见例如http://www-graphics.stanford.edu/~seander/bithacks.html。您可以修改其中一些算法,并跳过反演阶段。

答案 1 :(得分:5)

除非你专门寻找步数(即O(lg(n))的位数的理论改进,否则我认为你实际上不会比表查找更好,并且仍然有一个算法便携式的。

我希望在现代计算机上的单个线程上使用简单的表查找来轻松扫描超过1亿个IPv4网络掩码,以获得每秒领先的网络掩码(不包括实际获取IPv4网络掩码的工作)。我不确定进一步算法改进的收益是否值得任何增加的复杂性。

答案 2 :(得分:3)

如果在1之前所有位都为0,则可以使用BSF汇编程序指令,它将从低位开始返回第一位(非零)的索引,然后可以从32并获得设置的位数 否则,如果你必须从高位寻找,你可以使用 NOT 来反转这些位,并使用BSR从高位扫描到零。

答案 3 :(得分:2)

This question虽然完全不相关,却显示了一些用于执行CTZ / CLZ(计数前导/尾随零)的C代码。如果你在调用其中一个之前反转(按位),你可以得到前导/尾随的数量。