バイトからnビットを取得するのに少し苦労しています。
符号なし整数があります。 16進数の数値が0x2A、つまり10進数の42であるとします。バイナリでは次のようになります:0010 1010. 00101である最初の5ビットと010である次の3ビットを取得し、それらを別々の整数に配置する方法を教えてください。
誰かが私を助けることができれば、それは素晴らしいことです!私は単純に1バイトから抽出する方法を知っています
int x = (number >> (8*n)) & 0xff // n being the # byte
これはスタックオーバーフローに関する別の投稿で見ましたが、バイトから個別のビットを取得する方法がわかりませんでした。誰かが私を助けることができれば、それは素晴らしいことです!ありがとう!
整数はマシン内でビットのシーケンスとして表されます。私たち人間にとって幸いなことに、プログラミング言語はこれらの数値を10進数(または16進数)で表示するメカニズムを提供しますが、内部表現は変更されません。
ビット単位演算子&
、|
、^
および~
、およびシフト演算子<<
および>>
を修正する必要があります。このような問題を解決する方法を理解しています。
整数の最後の3ビットは次のとおりです。
x & 0x7
最後の8ビットから始まる5ビットは次のとおりです。
x >> 3 // all but the last three bits
& 0x1F // the last five bits.
Cの整数型の「取得」部分は次のように機能します。
&
を使用して、必要なビットをマスクします-1は「このビットをコピー」を意味し、0は「無視」を意味しますだから、あなたの例で。番号int x = 42;
があるとしましょう
最初の5ビット:
(x >> 3) & ((1 << 5)-1);
または
(x >> 3) & 31;
下位3ビットを取得するには:
(x >> 0) & ((1 << 3)-1)
または:
x & 7;
上からhi
ビット、下からlo
ビットが必要だとします。 (あなたの例では5と3)
top = (n >> lo) & ((1 << hi) - 1)
bottom = n & ((1 << lo) - 1)
説明:
topの場合、まず下位ビットを取り除き(右にシフト)、次に「すべて1」マスクで残りをマスクします(0010000
などの2進数がある場合は1を減算します)結果0001111
-元の数に1
- sと同じ数の0
sがあります)。
ボトムについても同じです。最初のシフトを気にする必要はありません。
top = (42 >> 3) & ((1 << 5) - 1) = 5 & (32 - 1) = 5 = 00101b
bottom = 42 & ((1 << 3) - 1) = 42 & (8 - 1) = 2 = 010b
これにはビットフィールドを使用できます。ビットフィールドは、変数をビットで指定できる特別な構造体です。
typedef struct {
unsigned char a:5;
unsigned char b:3;
} my_bit_t;
unsigned char c = 0x42;
my_bit_t * n = &c;
int first = n->a;
int sec = n->b;
ビットフィールドの詳細については、 http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION0013200000000000000
ビットフィールドの魅力は、シフト演算子などを扱う必要がないことです。表記法は非常に簡単です。いつものようにビットを操作すると、移植性の問題があります。
int x = (number >> 3) & 0x1f;
最後の5ビットがnumber
の8-4ビットであり、他のビットにゼロがある整数を与えます。
同様に、
int y = number & 0x7;
最後の3ビットがnumber
の最後の3ビットに設定され、残りにゼロが設定された整数が得られます。
コードの8 *を取り除くだけです。
int input = 42;
int high3 = input >> 5;
int low5 = input & (32 - 1); // 32 = 2^5
bool isBit3On = input & 4; // 4 = 2^(3-1)