2012-11-16 4 views
5

I flags di memoria utilizzano bit all'interno di un numero intero di 64 bit.
Voglio sapere se c'è un unico set po 'qualunque sia la posizione all'interno del intero a 64 bit (E.I. non mi interessa circa la posizione di qualsiasi specifico bit).Verificare se è impostato un solo bit all'interno di un numero intero (qualunque sia la sua posizione)

boolean isOneSingleBitSet (long integer64) 
{ 
    return ....; 
} 

potevo contare il numero di bit che utilizzano il Bit Twiddling Hacks (by Sean Eron Anderson), ma mi chiedo qual è il modo più efficace per rilevare solo se un singolo bit è impostato ...

ho trovato alcune altre questioni correlate:

e anche alcune pagine di Wikipedia:

NB: la mia domanda è in Java, ma sono curioso di ottimizzazioni usando altre lingue ...


EDIT: Lưu Vĩnh Phúc ha sottolineato che il mio primo collegamento all'interno della mia domanda ha già ottenuto la risposta: vedere la sezione Determining if an integer is a power of 2 nel Bit Twiddling Hacks (di Sean Eron Anderson). Non mi sono reso conto che un singolo bit era lo stesso di potenza di due.

+1

Per Java, prenderei in considerazione l'utilizzo della classe BitSet per questo scopo che supporta il metodo isEmpty() e molti altri che semplificano l'uso dei flag di bit. – maximdim

+1

è già in Bit Twiddling Hacks collegato sopra: [Determinare se un numero intero è una potenza di 2] (http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2) –

+0

Oh! Grazie :-) Aggiorno la mia domanda :-) Saluti – olibre

risposta

14

Se hai appena letteralmente vuole verificare se è impostato un singolo bit, allora si sono essenzialmente controllando se il numero è una potenza di 2. Per fare questo si può fare:

if ((number & (number-1)) == 0) ... 

Questo sarà anche contare 0 come una potenza di 2, così si dovrebbe verificare il numero non essendo 0 se questo è importante.Allora:

if (number != 0 && (number & (number-1)) == 0) ... 
+0

Risposta perfetta! – Ali

+0

Mi dispiace, ma ho provato la tua risposta, ho questi risultati: '0'->' false' (** ok **); '1'->' true' (** ok **); '2'->' false' (** KO **); '3'->' false' (** ok **); '4'->' false' (** KO **) '5'->' false' (** ok **) ... Per favore, puoi controllare anche dalla tua parte? – olibre

+0

Dai un'occhiata alla seconda versione in cui ho spiegato come sarebbe il risultato con il controllo per! = 0. Va bene, per quanto posso vedere. –

1

Supponendo di avere già un efficiente - o hardware - realizzazione di ffs() - trova prima serie - si può agire come segue:

bool isOneSingleBitSet (long integer64) 
{ 
    return (integer64 >> ffs(integer64)) == 0; 
} 

La funzione ffs() potrebbero essere già disponibili, o come si può vedere your own link above

+0

è 'ffs()' disponibile in java? – olibre

+0

+1 la tua risposta è valida :-) ma testata usando GCC '__builtin_ffs()'. Per favore dimmi se 'ffs()' è disponibile in java ... – olibre

+0

Non sono uno sviluppatore Java! Appena interessato alla tua domanda – Ali

2

la classe avvolgitore java.lang.Long ha una funzione statica bitCount() che restituisce il numero di bit in un lungo (64 bit int):

boolean isSingleBitSet(long l) 
{ 
    return Long.bitCount(l) == 1; 
} 

Nota che interi sono a 32-bit in java.

+2

Cambiando la condizione a == 1, funzionerà, ma quasi certamente non è il modo più efficace per rilevare un singolo bit, in senso stretto. –

+0

Conosci il sovraccarico di questo metodo? Questa è sicuramente la soluzione più leggibile anche se non è la più veloce. –

+0

Come ora ('> 0'), questo controllerà che il numero sia diverso da zero (grazie a @NeilCoffey per averlo notato). –

0

Sembra come si può fare un bit e con una long rappresentazione del singolo bit si desidera controllare. Ad esempio, per controllare il LSB

return( (integer64 & 1L)!=0 ); 

o per controllare il quarto bit da destra

return( (integer64 & 8L)!=0 ); 
+0

ok ... ma come si controlla se c'è un singolo bit impostato? Controllate ogni 64 bit? – olibre

+1

Utilizzando il metodo in questa risposta, sì, ma non lo consiglierei. Ho capito la domanda iniziale come controllare un bit specifico, piuttosto che controllare ogni singolo bit come previsto. La domanda come la intendevi è più interessante e ben fornita da Neil Coffey e Jan Dvorak. – Pursuit

+0

Grazie a @Pursuit. Migliorerò un po 'la mia domanda per essere più comprensibile ;-) – olibre

1

lascia supporre X è un 64bit tra pieno di 0 exept quello che state cercando;

return ((64bitinteger&X)==X) 
+0

restituisce true quando '64bitinteger = 0' :-( – olibre

+0

qual è' X' nella risposta? Lo stesso di '64bitinteger'? – olibre

+0

1010101 se si desidera controllare se il 3 ° bit è 1 1010101 e 0010000 è uguale a 0010000 in questo esempio X = 0010000 – Ercan

15

(con x come argomento)

Rilevare se è impostato almeno un bit è facile:

return x!=0; 

Analogamente rilevare se un bit (secondo bit più basso) è impostato è facile :

return (x&2)!=0; 

Esattamente un bit è impostato se è una potenza di due. Questo funziona:

return x!=0 && (x & (x-1))==0; 
+0

C'è un modo per verificare quale bit è attivo? (Accanto al log) Grande trucco tra l'altro – hl3mukkel

+0

@ hl3mukkel potresti usare la divisione iterata (che è solo un modo per calcolare un logaritmo intero) .Se stai cercando qualcosa di più veloce , controlla http://stackoverflow.com/q/14429661/499214. L'uso di un logaritmo è sicuramente più leggibile, è soggetto a round problemi. –

+0

Grazie! Ho trovato [collegamento] (http://stackoverflow.com/a/20342282/2489327) per essere un approccio efficiente e pulito. – hl3mukkel

Problemi correlati