繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM