把一个字节组合成长的



我有一个int64(长)值和一个字节值。我想把它们合并在一起。我知道我的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

您可以使用位运算符来实现这一点。假设你想在你的长-长中牺牲8个最重要的比特。(如果您的长-长为负,请小心!符号存储为最高有效位,因此您将丢失符号!)

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

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位的内容。还有塔达!我们已经将一个字节存储在一个longlong中!

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

最后,要提取你的长-长,你只需要将比特转移到另一个方向。字节将被覆盖,您的long-long将和新的一样好!

为了便于使用,我会使用联合:

union longlong_and_byte {
    long long long_value;
    char char_values[8];
};
union longlong_and_byte test;
test.long_value = 4000;
// for little endian (x86 for example) the most significant byte is the last one
test.char_values[7] = 19;
// for big endian (PPC for example) the most significant byte is the first one
test.char_values[0] = 19;

printf("long long value is %ldnchar value is %dn"
, test.long_value & 0xFFFFFFFFFFFFFF // need to mask off the necessary bits, only works with unsigned
, test.char_values[7]
);

只是关于C:中的位操作的提示

   int i = 0x081500; //lsb is 0x00
   char b = 'x12';   //any byte
   char r;
   i = i | ( b & 0xff );     // will be 0x081512
   r = i & 0xff;  // again 0x12, equal to r
   i = i | ( (b & 0xff) << 16 ); // will be 0x120815000 because first b is shifted 16 bits (--> 0x120000)
   r = ( i >> 16 ) & 0xff;  // first i is shifted to 0x12, then use lsb
   /* important: this expects i >= 0 */

当然,long或long-long也一样。我希望这能帮助你理解如何使用位运算。

最新更新