1

まず第一に、これが可能かどうかを知りたいです: 数に含まれている場合と含まれていない場合がある、いくつかの未署名のショートを含む unsigned long があるとしましょう。例えば:

unsigned short int id1 = 3456,
                   id2 = 30998;

unsigned long long bitfld = id1|id2;

他の 2 つのフィールドを 0 と見なすことはできますか? また、OR はこれに適した操作ですか? その後、引数として bitfld を渡すとしましょう:

void dostuff (unsigned long long bf)
{
     //pseudo code
     if( the first field exists in bf)
         get first field;

     if( the second field exists in bf)
         get second field;

     //etc...
}

ビットフィールドの最初の16ビットをポーリングしてチェックし、再帰的にポーリングして検証し、0より大きい場合は保存する必要があると思います。しかし、これを行う方法がわかりません。ビットシフトのみのシフト左または右、したがって、除算または乗算のみですよね?


ぶつけてごめんなさい。ご回答いただきありがとうございますが、最終的にはよりシンプルで効率的な方法である内部構造を使用することになりました。おわかりのように、これは文字列を使って簡単に行うことができましたが、私の目的はコードのユーザーへの透明性、つまり簡単にプログラムできるようにすることでした。値を保持する内部構造を作成し、そのような構造を作成して返す public メソッドを作成したので、使いやすく、解析が高速です (ただし、スタックに (小さいとはいえ) 構造を割り当てるオーバーヘッドがあります。ビット フィールド ソリューションにはありませんが、悲しいかな)。

それでは皆様、ご回答ありがとうございます。

4

4 に答える 4

4

short int長さは 2 バイトですが、long long8 バイトであるため、何らかの長さの不一致があります。あなたはこれを意味しているかもしれません:

unsigned long long bitfld = id1|(id2<<16);

AND次のように ing することで占有されているフィールドがあるかどうかを確認できます。

void dostuff (unsigned long long bf)
{
     //pseudo code
     if(bf & 0xFFFF)
         return bf & 0xFFFF;

     if(bf & 0xFF00)
         return (bf & 0xFFFF0000) >> 32;

 //etc...
}
于 2010-01-08T00:18:10.520 に答える
2

ビットごとの OR 操作は、必要なものではありません。この操作により、既存のビットが新しいビットとマージされます。ビットを置き換える操作が必要です。

最初に、AND と NOT を使用してビットをクリアする必要があります。

unsigned short int id1 = 3456,
                   id2 = 30998;

unsigned long long bitfld;

unsigned short int all_ones = ~0;
const unsigned int id2_position = 1;
const unsigned int bits_to_shift_left = id2_position * sizeof(unsigned short) * CHAR_BIT;
unsigned long long mask = ~(all_ones << bits_to_shift_left);
bitfld = bitfld & mask; // Erase all bits in id2 position
bitfld = bitfld | (id2 << bits_to_shift_left); // Put value into second position.

メモリ スペースの不足が問題にならない限り、この種のビット パッキングは、開発の労力、検証時間、余分な実行時間に見合うものではありません。値を unsigned char の「パックされた」バッファに入れ、そのバッファを I/O で使用します。

于 2010-01-09T00:20:20.883 に答える
1

おそらく、ビットシフト演算子とその仕組みを確認する必要があります。単に行う場合: id1 | id2、基本的にすべてのビットを一緒にマッシュアップします。これらの値を後で個別に抽出することはできません。あなたがやりたかったことはid1 | (id2 << 16)、ユーザー alemjerus によって指摘されたようなものです。

意地悪せずに同じ目標を達成する別の方法は、ユニオンを使用することです。


   struct s_btfld {
       unsigned short int f1;
       unsigned short int f2;
       unsigned short int f3;
       unsigned short int f4;
   };

   union u_btfld {
       struct s_btfld     fields;
       unsigned long long value;
   };

これで、次のことができます。


   unsigned short int id1 = 3456, id2 = 30998;

   union u_btfld bitfld;

   bitfld.fields.f1 = id1;
   bitfld.fields.f2 = id2;

   dostuff(bitfld.value);

dostuff では、次の方法でフィールドを簡単に取得できます。


   void dostuff(unsigned long long bf) {

      union u_btfld a;

      a.value = bf;

      printf("id1 = %d\n", a.fields.f1);
      printf("id2 = %d\n", a.fields.f2);

   }
于 2010-01-09T02:07:46.047 に答える
0

unsigned short を 2 バイト、unsigned long を 4 バイトと仮定します。

unsigned short id1 = 0x0d80; //3456 decimal
unsigned short id2 = 0x7916; //30998 decimal
unsigned long bitfld = ((id2<<16)|id1)  //id2<<16 = 0x79160000, so bitfld = 0x79160d80
if ((bitfld & id1) == id1) {
    //id1 is in lower 2 bytes of bitfld
}
if ((bitfld>>16) &id2) == id2) { //bitfld>>16 = 0x00007916
    //id2 is in upper 2 bytes of bitfld
}

これは役に立ちますか?ビットを扱う場合、16 進値を扱うと何が起こっているかを視覚的に確認しやすくなります。

于 2010-01-08T03:14:23.033 に答える