2011-01-16 10 views

Antwort

18

Versuchen n & (n-1) wo &bitwise AND

n = 7 
n - 1 =6 

n & (n-1)=> 0 1 1 1 (7) 
      & 0 1 1 0 (6) 
      --------- 
      0 1 1 0 (done!) 

EDIT ist (als Antwort auf den Kommentar von Forest gegeben)

n = 6 
n - 1 = 5 

n & (n-1)=> 0 1 1 0 (6) 
      & 0 1 0 1 (5) 
      --------- 
      0 1 0 0 (done!) 
+1

@taspeotis: Überprüfen Sie die Frage noch einmal "Wie kann das rechte ** Set ** Bit nicht gesetzt werden?" –

+0

Ah, ja. Ich habe das Wort "Set" übersehen. –

+4

+1 Schön! Ich verstehe immer noch nicht, wie Menschen solche Lösungen so schnell sehen. – Dawson

0
unsigned int clr_rm_set_bit(unsigned int n) 
{ 
    unsigned int mask = 1; 
    while(n & mask) { 
     mask <<= 1; 
    } 
    return n & ~mask; 
} 
+1

Dies ist O (N), während Prasoons O (1) ist. Außerdem wollen Sie etwas mehr wie 'while (! (N & maske))' ', aber selbst das funktioniert nicht für' n = 0'. –

+1

Eigentlich ist diese Methode (wenn sie richtig implementiert ist) nicht "O (n)". Es ist "O (log (n))". Und da n durch die Größe eines unsigned int begrenzt ist, könnte man es auch O (1) nennen. – Artelius

+0

Richtig, sollte Grenzen haben für n == 0 und n

4

Ihre Frage unklar ist.

Wenn Sie nur nicht gesetztes Bit wollen 0, hier sind einige Methoden (mit leichten Variationen im Verhalten auf dem Typen beteiligt abhängig):

x &= -2; 
x &= ~1; 
x -= (x&1); 

Wenn Sie den niedrigsten Bit unter den Bits unscharf zu schalten möchten, sind Satz, hier sind einige Möglichkeiten:

x &= x-1; 
x -= (x&-x); 

anzumerken, dass x&-x auf das niedrigste Bit des x gleich, zumindest wenn x ist unsigned oder Zweierkomplement. Wenn Sie eine solche Bit-Arithmetik durchführen möchten, sollten Sie nur vorzeichenlose Typen verwenden, da vorzeichenbehaftete Typen unter bitweisen Operationen implementierungsdefiniertes Verhalten aufweisen.

+5

"Rightmost Set Bit" scheint völlig klar. Es war nur ein schlecht gewähltes Beispiel. –