c++ - 将一个字节组合成 long long

标签 c++ c bit-manipulation

我有一个 int64(这是一个 long long)值和一个字节值。我想将它们合并在一起。我知道我的 long long 值不使用 64 位。所以我想使用未设置的 8 位(最高有效位还是最低有效位?)将一个字节编码到其中。

稍后我想将它们分开以找到原始值和字节。

所以最好是函数或某种宏

typedef unsigned char byte;
typedef long long int64;

int64 make_global_rowid(int64 rowid, byte hp_id);

byte get_hp_id(int64 global_row_id);

int64 get_row_id(int64 global_row_id);

get_hp_id从合并后的值中分离返回字节,而get_row_id返回合并后的原始int64

最佳答案

您可以使用按位运算符来实现这一点。假设您想牺牲 long long 中的 8 个最高有效位。 (如果你的 long long 是负数要小心!符号存储为最高有效位,所以你会丢失符号!)

现在,要做到这一点,您可以:

byte get_hp_id(int64 global_row_id)
{
  return ((char)global_row_id);
}

int64 get_row_id(int64 global_row_id)
{
  return (global_row_id >> 8);
}

int64 make_global_rowid(int64 rowid, byte hp_id)
{
  return (rowid << 8 + hp_id)
}

对于小的解释,<<是位移运算符。它的作用是将所有位向右或向左移动。超出边界的位将丢失,不知从哪里来的位将设置为 0:

 1001001 << 2 == 0100100 // the first 1 is lost, and 2 "0" come from the right

在您的情况下,我们向右移动 8 位(为您的字节留出空间),因此 8 位最高有效位将永远丢失。 但是现在,我们有类似的东西:

(xxxxxxxx)(xxxxxxxx)(xxxxxxxx)(00000000)

这意味着我们可以在不修改原始值的情况下添加适合 8 位的任何内容。还有田田!我们在 long long 中存储了一个字节!

现在,要提取字节,您只需将其转换为字符即可。在转换期间,仅保存 8 个最低有效位(您的字节)。

最后,要提取您的 long long,您只需将位以相反的方式移动。字节会被覆盖,你的long long会和新的一样!

关于c++ - 将一个字节组合成 long long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17473905/

相关文章:

重载 I/O 运算符时的 C++ unicode 框字符绘制

c - 查看代码以读取外部 adc 值

c - 类似位运算符之间的区别

c++ - 手动更改 unsigned int 中的一组字节

c++ - 检索叶目录

c++ - 用 asm 代码交换 C++ 中的 2 个变量

c++ - 为什么我们应该将 `std::unique_lock` 放在本地范围内?

C 中无法打印最大行

c - sizeof(struct) 如何帮助提供 ABI 兼容性?

c - 将 4 字节 int 交织到 8 字节 int