2010-06-29 10 views
7

Creo que podría haber estado dormido en mi clase de CS cuando hablaron de Posiciones de bit, así que espero que alguien pueda echar una mano.Encontrar posiciones de bits en un entero de 32 bits sin signo

Tengo un entero sin signo de 32 bits (permite utilizar el valor: 28)

De acuerdo con algún tipo de documentación que voy otra vez, el valor del entero contiene banderas que especifican varias cosas.

Las posiciones de los bits dentro de la bandera están numeradas de 1 (bajo orden) a 32 (alto orden). Todos los bits de bandera indefinidos están reservados y deben establecerse en 0.

Tengo una tabla que muestra los significados de las banderas, con un significado para los números 1-10.

Espero que alguien pueda probar y explicarme qué significa todo esto y cómo encontrar los valores de "marca" de un número como, 28, basado en la posición de bit.

Gracias

Respuesta

8

2 8 convierte a 11100 en binario. Eso significa que los bits 1 y 2 no están configurados y los bits 3, 4 y 5 están configurados.

Unos pocos puntos: en primer lugar, cualquiera que realmente está acostumbrado a C suele empezar la numeración a 0 y no por 1. En segundo lugar, se puede probar de las banderas individuales con el operador AND (&), como en:

#define flag1 1 // 1 = 00 0001 
#define flag2 2 // 2 = 00 0010 
#define flag3 4 // 4 = 00 0100 
#define flag4 8 // 8 = 00 1000 
#define flag5 16 // 16 = 01 0000 
#define flag6 32 // 32 = 10 0000 

if (myvalue & flag1) 
    // flag1 was set 

if (myvalue & flag4) 
    // flag4 was set 

y así sucesivamente. También puede comprobar qué bits son puestos en un bucle:

#include <stdio.h> 

int main() { 
    int myvalue = 28; 
    int i, iter; 

    for (i=1, iter=1; i<256; i<<=1, iter++) 
     if (myvalue & i) 
      printf("Flag: %d set\n", iter); 
    return 0; 
} 

debe imprimir:

Flag: 3 set 
Flag: 4 set 
Flag: 5 set 
+0

Jerry, su primera parte sobre el valor binario tiene sentido, sin embargo estoy un poco de aire fusionados con el código que publicaste ... ¿A qué se refieren los elementos flag1, flag2, etc.? Cuando pongo lo que tienes, obtengo una salida que establece 4 y 8. No estoy seguro de a qué se refiere desde arriba, dijimos que los bits 3, 4 y 5 se establecieron – kdbdallas

+0

@kdbdallas: He agregado algunos comentarios al código que espero hagan que el significado de las banderas sea un poco más evidente. –

0

Suponiendo flags no tiene signo ...

int flag_num = 1; 
while (flags != 0) 
{ 
    if ((flags&1) != 0) 
    { 
     printf("Flag %d set\n", flags); 
    } 
    flags >>= 1; 
    flag_num += 1; 
} 

Si flags se firma debe reemplazar

flags >>= 1; 

con

flags = (flags >> 1) & 0x7fffffff; 
3

Para tener una int con el valor 0 o 1 que representa sólo el n ésimo bit de ese entero, el uso :

int bitN = (value >> n) & 1; 

Pero eso no suele ser lo que quieres hacer. Un lenguaje más común es la siguiente:

int bitN = value & (1 << n); 

En este caso bitN será 0 si el n ésimo bit no está establecido, y no cero en el caso de que el n ésimo bit está establecido. (Específicamente, será cualquier valor que salga solo con el n bit establecido).)

8

En lugar de bucle a través de cada bit, en su lugar puede recorrer sólo los bits de ajuste, que puede ser más rápido si espera que los bits que se establezcan escasamente:

asumir el campo de bits es de (número entero escalar) campo variable

while (field){ 
    temp = field & -field; //extract least significant bit on a 2s complement machine 
    field ^= temp; // toggle the bit off 
    //now you could have a switch statement or bunch of conditionals to test temp 
    //or get the index of the bit and index into a jump table, etc. 
} 

funciona bastante bien cuando el campo de bits no se limita al tamaño de un único tipo de datos, pero podría ser de algún tamaño arbitrario. En ese caso, puede extraer 32 bits (o el tamaño de su registro) a la vez, probarlos contra 0 y luego pasar a la siguiente palabra.

0

utilizar una función de registro, con base 2. En pitón, que se vería así:

import math 

position = math.log(value, 2) 

Si la posición no es un entero, entonces, más de 1 bit se pone a 1.

0

Un @ ligera variación de invaliddata respuesta-

unsigned int tmp_bitmap = x;   
while (tmp_bitmap > 0) { 
    int next_psn = __builtin_ffs(tmp_bitmap) - 1; 
    tmp_bitmap &= (tmp_bitmap-1); 
    printf("Flag: %d set\n", next_psn); 
} 
0
// You can check the bit set positions of 32 bit integer. 
// That's why the check is added "i != 0 && i <= val" to iterate till 
// the end bit position. 
    void find_bit_pos(unsigned int val) { 
      unsigned int i; 
      int bit_pos; 
      printf("%u::\n", val); 
      for(i = 1, bit_pos = 1; i != 0 && i <= val; i <<= 1, bit_pos++) { 
        if(val & i) 
          printf("set bit pos: %d\n", bit_pos); 
      } 
    } 
Cuestiones relacionadas