2011-01-16 14 views

Odpowiedz

18

Spróbuj n & (n-1) gdzie & jest 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 (w odpowiedzi na komentarz danego lasu)

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: Ponownie sprawdź pytanie "Jak można ustawić jego prawy ** ustawiony ** bit?" –

+0

Ah, tak. Przeoczyłem słowo "zestaw". –

+4

+1 Miło! Nadal nie rozumiem, jak ludzie tak szybko widzą takie rozwiązania. – Dawson

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

To jest O (N), podczas gdy Prasoon to O (1). Poza tym potrzebujesz czegoś więcej jak 'while (! (N & mask)), ale nawet to nie działa dla' n = 0'. –

+1

W rzeczywistości ta metoda (jeśli poprawnie zaimplementowana) nie jest "O (n)". To jest 'O (log (n))'. A ponieważ n jest ograniczone wielkością unsigned int, możesz również nazwać to O (1). – Artelius

+0

W prawo, powinieneś sprawdzić granice dla n == 0 i n

4

Twoje pytanie jest niejasne.

Jeśli chcesz tylko na wyłączony bitu 0, oto kilka sposobów (z niewielkimi zmianami w zachowaniu, w zależności od rodzaju zaangażowanych):

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

Jeśli chcesz rozbroić najniższą trochę wśród bitów, które są zestaw, oto kilka sposobów:

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

Zauważ, że x&-x jest równa najmniejszej odrobiny x, przynajmniej jeśli x jest niepodpisany lub kod uzupełnień do dwóch. Jeśli chcesz wykonać jakąś arytmetykę w ten sposób, powinieneś używać tylko typów bez znaku, ponieważ typy podpisów mają zachowanie zdefiniowane przez implementację w operacjach bitowych.

+5

"Prawy południowy set bit" wydaje się zupełnie jasne. To był po prostu źle wybrany przykład. –