我正在阅读有关De Bruijn序列的wikipedia,但我的问题对本文没有帮助,但解决了msvc编译器警告:
警告C4146:一元减运算符应用于无符号类型,结果仍未签名
这里是来自维基百科链接的代码,它会产生此警告:
unsigned int v;
int r;
static const int MultiplyDeBruijnBitPosition[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
r = MultiplyDeBruijnBitPosition[((uint32_t)((v & -v) * 0x077CB531U)) >> 27];
警告在(v & -v)
部分中产生。
我还不确定100%的工作原理,但我只知道我需要它,但是我的项目设置为可以在W4上干净地编译,而这很烦人,我应该如何在此处解决此警告?
我们可以以某种方式使用UINT_MIN
技巧吗?我没有尝试过任何东西,因为我不想以函数的结果而告终。
我的理解是,v & -v
应该提取出特定的位。
v & -v
旨在提取lsb的值:#include<iostream>
#include<bitset>
int main() {
for(unsigned i = 1; i < 21; ++i) {
std::cout <<std::bitset<8>(i)<<": ";
std::cout<<i<<": "<<(i & -i)<<"\n";
}
return 0;
}
00000001: 1: 1
00000010: 2: 2
00000011: 3: 1
00000100: 4: 4
00000101: 5: 1
00000110: 6: 2
00000111: 7: 1
00001000: 8: 8
00001001: 9: 1
00001010: 10: 2
00001011: 11: 1
00001100: 12: 4
00001101: 13: 1
00001110: 14: 2
00001111: 15: 1
00010000: 16: 16
00010001: 17: 1
00010010: 18: 2
00010011: 19: 1
00010100: 20: 4
使用无符号类型的二进制补码-v
可以伪造
~v + 1