Antworten:
Wenn Sie das k-te Bit von n wollen, dann tun Sie es
(n & ( 1 << k )) >> k
Hier erstellen wir eine Maske, wenden die Maske auf n an und verschieben dann den maskierten Wert nach rechts, um genau das gewünschte Bit zu erhalten. Wir könnten es ausführlicher schreiben als:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
Weitere Informationen zur Bitmaskierung finden Sie hier .
Hier ist ein Programm:
#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
kann es auch nützlich sein, die Daten auf a zu übertragen, da Sie alle erforderlichen Daten mit einer einzigen Operation erhalten.
Wie gewünscht, habe ich beschlossen, meinen Kommentar zur Antwort des Zeigefingers auf eine vollständige Antwort auszudehnen. Obwohl seine Antwort richtig ist, ist sie unnötig komplex. Darüber hinaus verwenden alle aktuellen Antworten vorzeichenbehaftete int
s, um die Werte darzustellen. Dies ist gefährlich, da die Rechtsverschiebung negativer Werte implementierungsdefiniert ist (dh nicht portierbar ist) und die Linksverschiebung zu undefiniertem Verhalten führen kann (siehe diese Frage ).
Durch Verschieben des gewünschten Bits nach rechts in die niedrigstwertige Bitposition kann eine Maskierung durchgeführt werden 1
. Es ist nicht erforderlich, für jedes Bit einen neuen Maskenwert zu berechnen.
(n >> k) & 1
Berechnen (und anschließend drucken) eines Arrays von Einzelbitwerten als vollständiges Programm:
#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);
}
Angenommen, Sie möchten alle Bits wie in diesem Fall berechnen und nicht ein bestimmtes, kann die Schleife weiter in geändert werden
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
Dies ändert sich input
an Ort und Stelle und ermöglicht dadurch die Verwendung einer Einzelbitverschiebung mit konstanter Breite, die bei einigen Architekturen effizienter sein kann.
Hier ist eine Möglichkeit, dies zu tun: Es gibt viele andere:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
Es ist schwer zu verstehen, warum die Verwendung einer Schleife nicht erwünscht ist, aber es ist einfach genug, die Schleife abzuwickeln:
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));
Oder konstante Ausdrücke in den letzten vier Anweisungen auswerten:
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
@prateek danke für deine Hilfe. Ich habe die Funktion mit Kommentaren zur Verwendung in einem Programm umgeschrieben. Erhöhen Sie 8 für weitere Bits (bis zu 32 für eine Ganzzahl).
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;
}
Wenn Sie keine Schleifen möchten, müssen Sie diese ausschreiben:
#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;
}
Wie hier gezeigt, funktioniert dies auch in einem Initialisierer.
Verwenden von std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
(n >> k) & 1
ist gleichermaßen gültig und erfordert keine Berechnung der Maske, da die Maske aufgrund von Verschiebungen vor dem Maskieren konstant ist und nicht umgekehrt.