我遇到了C ++问题。我需要修改int64值的四个最高位。 最高位必须为“ 1”,接下来的三位必须为“ 0”。其余的值不应更改。
能帮我吗?谢谢
答案 0 :(得分:3)
要将位设置为0,可以对位掩码使用按位与:
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
AND 0000111111111111111111111111111111111111111111111111111111111111
--------------------------------------------------------------------
0000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
要将位设置为1,可以对位掩码使用按位或:
0000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
OR 1000000000000000000000000000000000000000000000000000000000000000
-------------------------------------------------------------------
1000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
请注意,int64
是一个有符号整数,并且通过按位修改最高有效位的结果和/或具有实现定义的结果(实际上,这意味着该值取决于如何在负数上表示负数)。系统)。按位运算通常仅对无符号整数执行。
如果需要对位掩码进行签名,则生成位掩码本身会非常棘手。这是因为将正数左移到无法代表的范围内具有不确定的行为。最好创建一个未签名的掩码,然后重新解释它。
假设您实际上想使用无符号代替:
uint64_t input = whatever;
input &= 0x0FFFFFFFFFFFFFFFu;
input |= 0x8000000000000000u;
还可以使用移位生成位掩码,这是将不同大小的整数进行泛化的有用方法:
using U = some_unsigned_integer;
U last_byte_offset = (sizeof(U) - 1) * 8;
U and_mask = ~(U(0xF0) << last_byte_offset);
U or_mask = U(0x80) << last_byte_offset;
答案 1 :(得分:0)
首先创建3位掩码:
0b0111 << 60
然后使用此掩码清除该位:
x &= ~((uint64_t)0b0111 << 60)
最后设置最后一位:
x |= ((uint64_t)1 << 63)
实际上,您需要编辑带符号的8字节而不是无符号的字节,这有点奇怪。 也许您在设计中遇到了更深层次的问题。
修复了该int缺陷。
答案 2 :(得分:-1)
首先,我们需要一个掩码,该掩码在所有4个最高位中都为1:
int64 mask = ~ (int64(0xf) << 60);
我们做了什么? 0xf
是二进制00 ... 001111。我们将二进制数字向左移动了59个位置,因此它变为111100 ... 00,然后我们对整个对象求反,结果为000011 ... 11。
请注意强制转换为int64。没有它,0xf可能是32位整数,而0xf<<60
也是32位(它的值可以是任何值)。
现在清除最高4位:
x = x & mask;
但是我们需要最高位为1。为此,请按位执行或使用二进制100 ... 00进行操作:
x = x | (int64(1) << 63);
我们完成了。
答案 3 :(得分:-1)
x = (x | 0x80000000) & 0x8fffffff ;
第一部分(x | 0x80000000)
将最高位设置为1。
第二部分& 0x8fffffff
将下三个最高位设置为零。