C++ 如何得到一个数字的按位not,但不否定符号位?

C++ 如何得到一个数字的按位not,但不否定符号位?,c++,c,C++,C,我有一个代表掩模的数字,我想得到负掩模(0110,即6)。我想按位不做,但它似乎也否定了符号位,我得到了一个不需要的值 size_t msk = 9; // that is 1001, or 000...01001 on more bits size_t nMsk = ~msk; // this I want to be 6, that is 0110, but bitwise not // is negating all the bits, so I

我有一个代表掩模的数字,我想得到负掩模(0110,即6)。我想按位不做,但它似乎也否定了符号位,我得到了一个不需要的值

size_t msk = 9; // that is 1001, or 000...01001 on more bits
size_t nMsk = ~msk; // this I want to be 6, that is 0110, but bitwise not  
                    // is negating all the bits, so I get 111...10110
有没有一种快速的方法(没有循环)

编辑 更多信息:

我在其中一个答案的评论中添加了一些更好的例子:
在我的例子中,16是100000000,~16不是111011111,而是00001111111

如果您希望您的值如您所要求的那样是6,那么您需要删除它前面的所有未使用的位

size\u t nMsk=(~msk)&0xF


用二进制的
0xF
屏蔽它,它等于
1111
,将删除除最后4位之外的所有位,从而得到所需的值。

如果您希望按照要求将值设为6,则需要删除它前面所有未使用的位

size\u t nMsk=(~msk)&0xF


用二进制中的
0xF
屏蔽它,它等于
1111
,将删除除最后4位以外的所有位,从而得到所需的值。

符号位只是反转,因为~不考虑有符号/无符号。例如:

uint8_t a = 54; /*     0011 0110 */
uint8_t b = ~a; /* 201 1100 1001 */

int8_t c = 54; /*      0011 0110 */
int8_t d = ~c; /* -55  1100 1001 */
如果只想反转某些位,可以使用xor,例如:

uint8_t a = 54;     /*     0011 0110 */
uint8_t b = a ^ 15; /* 57  0011 1001 */

符号位正好相反,因为~不考虑有符号/无符号。例如:

uint8_t a = 54; /*     0011 0110 */
uint8_t b = ~a; /* 201 1100 1001 */

int8_t c = 54; /*      0011 0110 */
int8_t d = ~c; /* -55  1100 1001 */
如果只想反转某些位,可以使用xor,例如:

uint8_t a = 54;     /*     0011 0110 */
uint8_t b = a ^ 15; /* 57  0011 1001 */

如何通过按位异或保留符号位:

size_t nMsk = ~msk ^ (1 << ((sizeof(size_t) * CHAR_BIT) - 1));

size\t nMsk=~msk^(1如何通过按位异或保留符号位:

size_t nMsk = ~msk ^ (1 << ((sizeof(size_t) * CHAR_BIT) - 1));

size\t nMsk=~msk^(1OP在一条注释中指出,他事先不知道位数。解决这个问题的一个方法是使用查找表。这方面的一个8位示例是

uint8_t lookup[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
result ^= lookup [numberofbits];

OP在一条评论中说,他事先不知道位数。解决这个问题的一种方法是使用查找表。8位的例子是

uint8_t lookup[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
result ^= lookup [numberofbits];

如果你对你正在使用的最大位数做一个假设,你可以得到一个“所有位都在最高设定位或低于最高设定位”的掩码,而不需要太多的魔法(尽管魔法可能更快)

然后用XOR表示:

nMsk = msk ^ m;

虽然这是一个不寻常的操作,但我仍然怀疑你真的是指其他的东西。

如果你假设你正在使用的最大位数,你可以得到一个“所有位都位于或低于最高设定位”的掩码,而不需要太多的魔法(尽管魔法可能更快)

然后用XOR表示:

nMsk = msk ^ m;
虽然这是一个不寻常的操作,但我仍然怀疑你真的是指其他事情。

以下是我的尝试():

#包括
#包括
#包括
#包括
模板
T构建_掩码(T num){
const int up_to_bit=ceil(log2(num));
for(int i=0;i
#包括
#包括
#包括
#包括
模板
T构建_掩码(T num){
const int up_to_bit=ceil(log2(num));
for(int i=0;i
num |=1这是干什么的?你确定这就是问题所在吗?通常当人们想要这样的东西时,结果是他们被额外的设置位分散了注意力,结果证明他们不是问题。如果你使用的是4位数字,那很简单:
nMsk=msk^15
不,我使用的是较大的数字,但很容易显示出来在4位:)Sorry唯一的方法是将值设置为1的XOR,最多。
size\t
是无符号的!因此它在定义上没有符号位。您的问题不清楚。@sop:不,不是。这可能是XY问题。您提出的“解决方案”背后的实际问题是什么?这是干什么的?你确定这就是问题所在吗?通常当人们想要这样的东西时,结果是他们被额外的设置位分散了注意力,结果证明他们不是问题。如果你使用的是4位数字,那很简单:
nMsk=msk^15
不,我使用的是较大的数字,但在4位上很容易显示出来ts:)Sorry唯一的方法是将值设置为1的XOR,最多。
size\u t
是无符号的!因此它在定义上没有符号位。您的问题不清楚。@sop:不,不清楚。这可能是XY问题。您提出的“解决方案”背后的实际问题是什么?我也测试了这个想法,但似乎我应该知道掩码使用的位数,但我不确定这是否是固定的…这就是为什么我要求一些知道从我的数字中删除1的东西。您的用例是什么?我的用例是0x1b7,我期望的是0x48,但我希望它也适用于0x10(返回0xF)我也测试了这个想法,但似乎我应该知道掩码使用的位数,但我不确定这是否是固定的…这就是为什么我要求一些知道从我的数字中删除1的东西。您的用例是什么?我的用例是0x1b7,我期望的是0x48,但我希望它也适用于0x10(返回0xF)这是线索,它被移动到符号位的位置,对于4字节的
大小,移动将是
1对不起,你完全正确,我想我回答你的时候没有完全清醒;)好的,对于“符号位”,我指的是x位掩码前面的1(例如16是100000000,~16不是111000000000,但在我的例子中是00001111111)这就是线索,它被移动到符号位的位置,对于一个4字节的
size\u t
,移动将是
1对不起,你完全正确,我想我回答你的时候我还没有完全醒来;)好的,用“符号位”我的意思是x位掩码前面的1(例如16是100000000,~16不是111000000000,但在我的例子中是00001111111),除了OP仍然需要找到数字中的位数,这可能需要一个循环。除了OP仍然需要找到b的位数