获取整数bitset中前导1位置的最快方法
Quickest way to get the position of the leading 1 in a bitset for an integer?
考虑这个程序
#include <iostream>
#include <bitset>
#include <cstdint>
#include <cstdlib>
typedef uint8_t Tnum;
template <typename T>
void printBits(T a)
{
std::cout << std::bitset<(sizeof(a) * 8)>(a).to_string() << 'n';
}
int main()
{
printBits(Tnum(15));
printBits(Tnum(17));
return EXIT_SUCCESS;
}
它打印
00001111
00010001
现在考虑前面输出
中的这两个家伙00001111
^
00010001
^
我想知道如何,给定有符号或无符号整数类型,并给定该类型实例的值,我可以获得模式中领先1
的位置,从0
开始计数,我期望的结果是3
为第一行,4
为第二行。所涉及的位置总数对我来说也是可以接受的,比如第一行用4
,第二行用5
。
我现在没有Hacker's Delight或类似的文本可用,我找不到任何快速的旋转。
这有点像它,但它很容易出错,它永远不会通过转换测试或一组关于转换的警告标志,至少在我的情况下。而且这可能不是最优选择。
请不要查找表,我愿意接受任何不会导致转换问题且不使用LUT的东西。C89/99和c++ 11
如果这是X86并且您可以使用汇编,则有位扫描反向指令。根据编译器的不同,这可能有一个内在的
位扫描反转
为什么你不能进入黑客的喜悦?代理限制?
这是来自http://www.hackersdelight.org/hdcodetxt/nlz.c.txt
的解决方案int nlz1(unsigned x) {
int n;
if (x == 0) return(32);
n = 0;
if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
if (x <= 0x7FFFFFFF) {n = n + 1;}
return n;
}
正如其他人所说,x86-64处理器具有最高有效位(MSB)指令,可以通过编译器使用内联汇编或编译器指令(intrinsic )访问该指令。Microsoft C编译器有_BitScanReverse 32位指令。
如何为gcc编译器插入内联汇编代码的示例可以在这里找到:https://www.biicode.com/pablodev/pablodev/bitscan/master/25/bitboard.h
如果您对这种类型的解决方案不感兴趣,那么使用de Bruijn幻数在表大小和速度之间取得良好折衷的O(log(N))解决方案是:
uint32_t v;
int r;
static const int MultiplyDeBruijnBitPosition[32] =
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
基本上,首先将输入的数字四舍五入到小于2次幂的1,然后进行de Bruijn乘法和查找。当已知输入数是2的幂时(但幻数是不同的),移位是不必要的。
如果你正在使用visual studio,你可以使用BitScanRevers intrinsic
- 如何定义更改car类中car位置的方法
- 映射唯一值和重复值的有效方法.可以访问键或值的位置
- 当使用Lua作为嵌入式语言(比如c++)时,有什么简单/方便的方法可以找到变量在Lua中的定义位置吗
- C++11 中的随机数:有没有一种简单的方法可以将生成器种子放在代码的一个位置,然后在不同的函数中使用它?
- 这是查找向量中元素位置的合法方法吗?
- 最简单的方法使多个指针一次指向同一位置,一次只处理2个位置
- 从方法中获得链接列表中的位置
- Qt:交换QGraphicsRectItem位置的最佳方法是什么
- 有没有一种方法可以在std::向量的特定位置重复插入元素
- 根据这些字符串输入在句子中的位置对这些字符串输入进行排序的更快方法是什么
- 正确实施位置的方法在C 中
- 使用DirectX/C++在不同位置渲染多个网格对象的有效方法
- 检查阵列位置在C++中是否为空的 CPU 高效方法
- 使用 2x1 和 1x2 多米诺骨牌平铺具有禁止位置的 2xN 网格的方法数量
- std::字符串 在安全位置截断 UTF-8 的最佳方法
- 有没有使用 str.substr( ) 在给定位置提取子字符串的替代方法
- 如何解决调用 dll 方法时的访问冲突写入位置
- 查找控件相对于其父窗口的位置的最佳方法是什么?
- 当从不同位置访问类方法时,类成员的位置会发生变化
- 有没有一种方法可以从特定的内存位置分配内存