[英]Set the highest four bits of a int64 value in c++
我有一个C ++问题。 我需要修改int64值的四个最高位。 最高位必须为“ 1”,接下来的三位必须为“ 0”。 该值的其余部分不应更改。
你能帮我吗。 谢谢
要将位设置为0,可以对位掩码使用按位与:
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
AND 0000111111111111111111111111111111111111111111111111111111111111
--------------------------------------------------------------------
0000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
要将位设置为1,可以对位掩码使用按位或:
0000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
OR 1000000000000000000000000000000000000000000000000000000000000000
-------------------------------------------------------------------
1000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
请注意, int64
是有符号整数,并且是按位修改最高有效位的结果,并且/或者具有实现定义的结果(实际上,这意味着该值取决于系统上如何表示负数)。 按位运算通常仅对无符号整数执行。
如果需要对位掩码进行签名,则生成位掩码本身就非常棘手。 这是因为将正数左移到无法代表的范围内具有不确定的行为。 最好创建一个未签名的掩码,然后重新解释它。
假设您实际上想使用unsigned代替:
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;
首先为3位创建掩码:
0b0111 << 60
然后使用此掩码清除该位:
x &= ~((uint64_t)0b0111 << 60)
最后设置最后一点:
x |= ((uint64_t)1 << 63)
实际上,有点奇怪,您需要编辑带符号的8字节的位,而不是无符号的。 也许您的设计中存在一些更深层次的问题。
修复了int缺陷。
首先,我们需要一个掩码,该掩码在所有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);
我们完了。
x = (x | 0x80000000) & 0x8fffffff ;
第一部分(x | 0x80000000)
将最高位设置为1。 第二部分& 0x8fffffff
将下三个最高位设置为零。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.