Réponses:
Si vous voulez le k-ième bit de n, alors faites
(n & ( 1 << k )) >> k
Ici, nous créons un masque, appliquons le masque à n, puis décalons à droite la valeur masquée pour obtenir exactement le bit que nous voulons. Nous pourrions l'écrire plus complètement comme:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
Vous pouvez en savoir plus sur le masquage de bits ici .
Voici un programme:
#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
peut également être utile, car vous obtenez toutes les données requises en une seule opération.
Comme demandé, j'ai décidé d'étendre mon commentaire sur la réponse de l'index à une réponse à part entière. Bien que sa réponse soit correcte, elle est inutilement complexe. De plus, toutes les réponses actuelles utilisent des int
s signés pour représenter les valeurs. Ceci est dangereux, car le déplacement vers la droite des valeurs négatives est défini par l'implémentation (c'est-à-dire non portable) et le déplacement vers la gauche peut conduire à un comportement indéfini (voir cette question ).
En décalant vers la droite le bit souhaité dans la position de bit la moins significative, le masquage peut être effectué avec 1
. Pas besoin de calculer une nouvelle valeur de masque pour chaque bit.
(n >> k) & 1
En tant que programme complet, calculer (puis imprimer) un tableau de valeurs à un seul bit:
#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);
}
En supposant que vous vouliez calculer tous les bits comme dans ce cas, et non un spécifique, la boucle peut être modifiée en
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
Cela modifie input
en place et permet ainsi l'utilisation d'un décalage de largeur constante d'un bit, ce qui peut être plus efficace sur certaines architectures.
Voici une façon de procéder. Il en existe de nombreuses autres:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
Il est difficile de comprendre pourquoi l'utilisation d'une boucle n'est pas souhaitée, mais il est assez facile de dérouler la boucle:
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));
Ou évaluer des expressions constantes dans les quatre dernières instructions:
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
@prateek merci pour votre aide. J'ai réécrit la fonction avec des commentaires pour une utilisation dans un programme. Augmentez 8 pour plus de bits (jusqu'à 32 pour un entier).
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;
}
Si vous ne voulez pas de boucles, vous devrez l'écrire:
#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;
}
Comme démontré ici, cela fonctionne également dans un initialiseur.
En utilisant std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
(n >> k) & 1
est également valide et ne nécessite pas de calculer le masque car le masque est constant en raison du décalage avant le masquage au lieu de l'inverse.