2013-03-10 38 views
5

używałem std::bitset<N> w moim programie i potrzebne do znalezienia najmniej znaczący ustawiony bit i zrobił to trywialne obliczenia jak poniżej:Czy istnieje trywialny sposób, aby uzyskać 2 za uzupełnienie std :: bitset <N>

int num = 5; 
int res = num & (-num); 

Po czym najmniej znaczący bit num jest ustawiony na res i pozostałe są 0. Działa to jako -5 jest reprezentowane w notacji uzupełnienia 2-go.

Ale znalazłem std::bitset<N> nie ma przeciążenia operatora dla unary operator -, który dałby mi uzupełnienie 2 dla podstawowych bitów. Czy istnieje prosty sposób implementacji uzupełnienia dwójki z std::bitset<N>? Zawsze mogłem użyć operator ~, aby odwrócić bity i wykonać pętlę, wykonując sumę i przenoszenie, zaczynając od LSB na MSB, ale szukałem rozwiązania, które by tego uniknęło.

+2

Z pewnością istnieje wiele ** nietrywialnych ** sposobów robienia niemal wszystkiego! – rodrigo

+0

Zauważyłem, że powinienem był użyć __trivial__ :-p Dokonam edycji tytułu. – vvnraman

+2

Zauważ, że zapętlanie nad odwróconym bitsetem jest najprawdopodobniej tak szybkie, jak zwykłe zapętlenie nad oryginalnym bitsetem w celu znalezienia najmniej znaczącego bitu (co znajduję w tym przypadku trywialne rozwiązanie;)) – Zeta

Odpowiedz

2

std::bitset nie przewiduje żadnych metod dopełniacza. Ponieważ trzeba by obliczyć uzupełniają się z operator~ oraz dodatkową pętlę, po prostu pomiń operator~() i szukać LSB bezpośrednio:

template <int N> 
size_t least_significant_bit(const std::bitset<N> &bt){ 
    for(size_t i = 0; i < bt.size(); ++i){ 
     if(bt.test(i)) 
      return i; 
    } 
} 

myślę, że nie można dostać więcej niż banalne;).

Należy zauważyć, że wynik least_significant_bit nie został określony, jeśli nie ma wcale bitów. Można zwrócić N lub zmienić pętlę, aby przetestować bt.test(N), który spowodowałby wyjątek, ale ostatecznie nie ma sensu szukać LSB w pustym bitsecie.

Co więcej, można użyć std::bitset<N>::operator[] zamiast std::bitset<N>::test, jeśli nie są Państwo zainteresowani sprawdzaniem granic.

+0

Przepraszam za bałagan indeksowy, myślałem w kategoriach [to_string() '] (http://en.cppreference.com/w/cpp/utility/bitset/to_string) (*" Wynikowy ciąg zawiera N znaki z pierwszym znakiem odpowiadają ostatniemu (N-1) bitowi i ostatniemu znakowi odpowiadającemu pierwszemu bitowi. "*) zamiast używać prostej logiki bitowej>. < – Zeta

0

dość wygodny sposób za to uzupełnienie dwójkowe jest znalezienie najmniej znaczący 0 w swoim bitset, ustanawiając, że na 1 i ustawieniu wszystkich mniej znaczących bitów 0.

Pseudokod: (zakładając, że zbiór [0] jest najmniej znaczący bit, jeśli nie, należy obrócić ją wokół)

int i = 0; 
while (i < set.length && set[i]) 
    { 
    set[i] = 0; 
    ++i; 
    } 

if (i < set.length) 
    set[i] = 1; 
+1

Nie ma operatora '' ani 'operatora +', stąd niedogodność :-) – vvnraman

+0

@vvnraman masz rację. Zaktualizowałem swoją odpowiedź. –

+0

nie zapomnij poradzić sobie ze wszystkimi przypadkami: – assem