2010-06-29 14 views
7

Penso che avrei potuto essere addormentato nella mia classe CS quando hanno parlato di Bit Positions, quindi spero che qualcuno possa dare una mano.Trovare posizioni di bit in un numero intero a 32 bit senza segno

Ho un senza segno a 32 bit integer (Consente di utilizzare il valore: 28)

Secondo alcuni documenti che sto sopra, il valore del numero intero contiene flag che specificano varie cose.

Le posizioni bit all'interno del flag sono numerate da 1 (ordine basso) a 32 (ordine alto). Tutti i bit di flag non definiti sono riservati e devono essere impostati su 0.

Ho una tabella che mostra il significato dei flag, con significato per i numeri 1-10.

Spero che qualcuno possa provare a spiegarmi cosa significa tutto questo e come trovare il valore "flag" da un numero come, 28, in base alla posizione del bit.

Grazie

risposta

8

2 8 converte in 11100 in binario. Ciò significa che i bit 1 e 2 non sono impostati e i bit 3, 4 e 5 sono impostati.

Alcuni punti: in primo luogo, chi è veramente abituato a C di solito inizia la numerazione da 0, non 1. In secondo luogo, è possibile verificare delle singole bandiere con il bit a bit e l'operatore (&), come in:

#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 

e così via. È anche possibile controllare che i bit sono impostati in un ciclo:

#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; 
} 

dovrebbe stampare:

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

Jerry @ del invaliddata, la vostra prima parte che riguarda il valore binario ha un senso, ma io sono un po 'con fuso sul codice che hai postato ... Hai le referenze di flag1, flag2, etc? Quando metto quello che hai, ottengo l'output che 4 e 8 sono impostati. Non so a cosa si riferisca da quando abbiamo detto che i bit 3, 4 e 5 sono stati impostati – kdbdallas

+0

@kdbdallas: Ho aggiunto alcuni commenti al codice che spero rendano un po 'più evidente il significato delle bandiere. –

0

assumendo flags non è firmato ...

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

Se flags è firmato è necessario sostituire

flags >>= 1; 

con

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

per ottenere un int con il valore 0 o 1 che rappresenta solo il n esimo bit da quello intero, l'uso :

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

Ma di solito non è quello che si vuole fare. Un linguaggio più comune è questo:

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

In questo caso sarà bitN0 se il n esimo bit non è impostato, e non zero nel caso in cui il n esimo bit è impostato. (In particolare, sarà qualsiasi valore venga fuori con solo il n bit impostato.)

8

Invece di girare su ogni singolo bit, è possibile invece scorrere solo i bit impostati, che può essere più veloce se si prevede che i bit da scarsamente impostare:

Assumere il campo di bit è in (intero scalare) campo variabile.

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. 
} 

funziona abbastanza bene quando il campo bit non si limita alla dimensione di un singolo tipo di dati, ma potrebbe essere di qualche dimensione arbitraria. In tal caso, puoi estrarre 32 (o qualunque sia la dimensione del registro) bit alla volta, testarlo contro 0 e quindi passare alla parola successiva.

0

utilizza una funzione di log, con base 2. In pitone, che sarebbe simile:

import math 

position = math.log(value, 2) 

Se la posizione non è un intero, quindi più di 1 bit è stato impostato a 1.

0

A leggera variazione di risposta-

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); 
      } 
    } 
Problemi correlati