在C ++中设置int64值的最高四位

时间:2019-07-08 13:40:39

标签: c++ bit

我遇到了C ++问题。我需要修改int64值的四个最高位。 最高位必须为“ 1”,接下来的三位必须为“ 0”。其余的值不应更改。

能帮我吗?谢谢

4 个答案:

答案 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将下三个最高位设置为零。