应用于无符号类型的一元减运算符

问题描述 投票:0回答:1

我正在阅读有关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应该提取出特定的位。

c++ compiler-warnings
1个回答
0
投票
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

© www.soinside.com 2019 - 2024. All rights reserved.