回答:
nのk番目のビットが必要な場合は、次のようにします。
(n & ( 1 << k )) >> k
ここでは、マスクを作成し、マスクをnに適用してから、マスクされた値を右シフトして、必要なビットだけを取得します。次のように完全に書き出すことができます。
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
ビットマスキングの詳細については、こちらをご覧ください。
ここにプログラムがあります:
#include <stdio.h>
#include <stdlib.h>
int *get_bits(int n, int bitswanted){
int *bits = malloc(sizeof(int) * bitswanted);
int k;
for(k=0; k<bitswanted; k++){
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
bits[k] = thebit;
}
return bits;
}
int main(){
int n=7;
int bitswanted = 5;
int *bits = get_bits(n, bitswanted);
printf("%d = ", n);
int i;
for(i=bitswanted-1; i>=0;i--){
printf("%d ", bits[i]);
}
printf("\n");
}
struct
使用する場合、1回の操作で必要なすべてのデータを取得できるため、データをにキャストすることも役立ちます。
リクエストに応じて、人差し指の回答に関するコメントを本格的な回答に拡張することにしました。彼の答えは正しいですが、それは不必要に複雑です。さらに、現在のすべての回答でint
は、値を表すために符号付きsを使用しています。負の値の右シフトは実装定義(つまり、移植不可能)であり、左シフトは未定義の動作につながる可能性があるため、これは危険です(この質問を参照)。
目的のビットを最下位ビット位置に右シフトすることにより、でマスキングを行うことができます1
。各ビットの新しいマスク値を計算する必要はありません。
(n >> k) & 1
完全なプログラムとして、単一ビット値の配列を計算(およびその後に出力)します。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
unsigned
input = 0b0111u,
n_bits = 4u,
*bits = (unsigned*)malloc(sizeof(unsigned) * n_bits),
bit = 0;
for(bit = 0; bit < n_bits; ++bit)
bits[bit] = (input >> bit) & 1;
for(bit = n_bits; bit--;)
printf("%u", bits[bit]);
printf("\n");
free(bits);
}
この場合のように、特定のビットではなく、すべてのビットを計算する場合、ループはさらに次のように変更できます。
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
これはinput
適切に変更され、それによって一定幅のシングルビットシフトの使用を可能にします。これは、一部のアーキテクチャではより効率的な場合があります。
これを行う1つの方法を次に示します。他にも多くの方法があります。
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
ループの使用が望ましくない理由を理解することは困難ですが、ループを展開するのは簡単です。
bool b[4];
int v = 7; // number to dissect
b [0] = 0 != (v & (1 << 0));
b [1] = 0 != (v & (1 << 1));
b [2] = 0 != (v & (1 << 2));
b [3] = 0 != (v & (1 << 3));
または、最後の4つのステートメントで定数式を評価します。
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
@prateek助けてくれてありがとう プログラムで使用するために、関数をコメント付きで書き直しました。ビットを増やすには8を増やします(整数の場合は最大32)。
std::vector <bool> bits_from_int (int integer) // discern which bits of PLC codes are true
{
std::vector <bool> bool_bits;
// continously divide the integer by 2, if there is no remainder, the bit is 1, else it's 0
for (int i = 0; i < 8; i++)
{
bool_bits.push_back (integer%2); // remainder of dividing by 2
integer /= 2; // integer equals itself divided by 2
}
return bool_bits;
}
ループが必要ない場合は、書き出す必要があります。
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num = 7;
#if 0
bool arr[4] = { (num&1) ?true: false, (num&2) ?true: false, (num&4) ?true: false, (num&8) ?true: false };
#else
#define BTB(v,i) ((v) & (1u << (i))) ? true : false
bool arr[4] = { BTB(num,0), BTB(num,1), BTB(num,2), BTB(num,3)};
#undef BTB
#endif
printf("%d %d %d %d\n", arr[3], arr[2], arr[1], arr[0]);
return 0;
}
ここで示されているように、これは初期化子でも機能します。
使用する std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
(n >> k) & 1
は等しく有効であり、逆にではなくマスキング前にシフトするためにマスクが一定であるため、マスクを計算する必要はありません。