Respuestas:
Si quieres el k-ésimo bit de n, hazlo
(n & ( 1 << k )) >> k
Aquí creamos una máscara, aplicamos la máscara an, y luego desplazamos a la derecha el valor enmascarado para obtener solo el bit que queremos. Podríamos escribirlo más completamente como:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
Puede leer más sobre el enmascaramiento de bits aquí .
Aquí hay un programa:
#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
archivo también puede ser útil, ya que obtiene todos los datos necesarios con una sola operación.
Como se solicitó, decidí extender mi comentario sobre la respuesta de índice a una respuesta completa. Aunque su respuesta es correcta, es innecesariamente compleja. Además, todas las respuestas actuales utilizan int
s con signo para representar los valores. Esto es peligroso, ya que el desplazamiento a la derecha de los valores negativos está definido por la implementación (es decir, no es portátil) y el desplazamiento a la izquierda puede conducir a un comportamiento indefinido (consulte esta pregunta ).
Al desplazar a la derecha el bit deseado a la posición de bit menos significativa, se puede realizar el enmascaramiento 1
. No es necesario calcular un nuevo valor de máscara para cada bit.
(n >> k) & 1
Como programa completo, calcula (y posteriormente imprime) una matriz de valores de un solo 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);
}
Suponiendo que desea calcular todos los bits como en este caso, y no uno específico, el bucle se puede cambiar más a
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
Esto se modifica input
en su lugar y por lo tanto permite el uso de un desplazamiento de un solo bit de ancho constante, que puede ser más eficiente en algunas arquitecturas.
Aquí hay una forma de hacerlo, hay muchas otras:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
Es difícil entender por qué no se desea el uso de un bucle, pero es bastante fácil desenrollar el bucle:
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));
O evaluar expresiones constantes en las últimas cuatro declaraciones:
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
@prateek gracias por tu ayuda. Reescribí la función con comentarios para usarla en un programa. Aumente 8 para obtener más bits (hasta 32 para un número entero).
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 no quiere ningún bucle, tendrá que escribirlo:
#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;
}
Como se demuestra aquí, esto también funciona en un inicializador.
Utilizando std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
(n >> k) & 1
es igualmente válido y no requiere calcular la máscara ya que la máscara es constante debido al cambio antes de enmascarar en lugar de al revés.