(少なくとも) 2 つの基本的なアプローチがあります。1 つは、いくつかのビットフィールドを持つ構造体を作成することです。
struct bits {
unsigned a : 1;
unsigned b : 7;
unsigned c : 4;
unsigned d : 3;
unsigned e : 1;
};
bits b;
b.a = val1;
b.b = val2;
b.c = val3;
b.d = val4;
b.e = val5;
16 ビット値を取得するには、(一例として) その構造体とuint16_t
. ちょっとした問題が 1 つだけあります。標準では、16 ビット値を見たときにビット フィールドが最終的にどのような順序になるかは保証されていません。たとえば、上で示した順序を逆にして、本当に必要な最上位ビットから最下位ビットへの順序を取得する必要がある場合があります (ただし、コンパイラを変更すると、再び混乱する可能性があります)。
もう 1 つの明白な可能性は、シフトとマスキングを使用して、ピースをまとめて数字にすることです。
int16_t result = val1 | (val2 << 1) | (val3 << 8) | (val4 << 12) | (val5 << 15);
今のところ、各入力は正しい範囲で始まる (つまり、選択したビット数で表現できる値を持つ) と想定しています。間違っている可能性がある場合は、最初に正しいビット数にマスクする必要があります。これを行う通常の方法は、次のようなものです。
uint16_t result = input & ((1 << num_bits) - 1);
そこの数学に興味がある場合は、次のように機能します。入力が 4 ビットに収まるようにしたいとします。1
左に 4 ビットシフトする00010000
と (バイナリで) 生成されます。それから 1 を引くと、設定されている 1 ビットがクリアされ、それより下位のすべてのビットが設定さ00001111
れます。これにより、最初の最下位ビット セットが得られます。それと入力の間でビットごとに行うAND
と、入力に設定された上位ビットは結果でクリアされます。