1

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 を返します。

4

3 に答える 3

3

これを実現するには、ビット単位の演算子を使用できます。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 に 1 バイトを格納しました。

ここで、バイトを抽出するには、それを char としてキャストするだけです。キャスト中、最下位 8 ビットのみが保存されます (あなたのバイト)。

最後に、long long を抽出するには、ビットを逆にシフトするだけです。バイトは上書きされ、 long long は新しいものと同じになります!

于 2013-07-04T15:51:39.067 に答える
0

使いやすさのために、ユニオンを使用します。

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 %ld\nchar value is %d\n"
, test.long_value & 0xFFFFFFFFFFFFFF // need to mask off the necessary bits, only works with unsigned
, test.char_values[7]
);
于 2013-07-04T16:00:25.427 に答える
0

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 */

もちろん、ロングまたはロングロングでも同じように機能します。ビット演算の使用方法を理解するのに役立つことを願っています。

于 2013-07-04T15:52:21.107 に答える