Maskowanie oraz operacje na bitach

0

Witam !

Mam problem z programem. Potrzebuje pomocy - głównie chodzi mi o pierwszą funkcję, za która zupełnie nie wiem jak mam się zabrać, żeby uzyskać właściwy format maski.

Napisz program, który będzie składał się z 3 funkcji:

  1. Funkcja tworząca maskę, maskowanie(int N, int M, int P)
    przyjmuje N - ilość jedynek, M - ile zer, P - ile powtórzeń.
    Przykładowe wywołania:
    maskowanie(1,2,1) -> wynik bitowo -> 100
    maskowanie(2,3,3) -> wynik bitowo -> 110001100011000

  2. Funkcja sprawdzająca, który jest najwyższy bit, licząc od prawej strony.
    jeśli liczba = 15 (1111), to
    ktoryBit(liczba) -> zwróci -> 4
    jeśli liczba = 64 (1000000), to
    ktoryBit(liczba) -> zwróci -> 7
    Można to osiągnąć np. przesuwaniem liczby w prawo i sprawdzaniem odpowiedniego warunku.

  3. Funkcje negująca i ustawiająca. Przyjmuje parametr, np. typu int (0-neguj, 1-ustaw).

Ogólnie program ma działać w ten sposób, że wczytujemy z konsoli liczbę. Maskujemy od najwyższego bitu w prawo (Najwyższy bit maski pokrywa się z najwyższym bitem liczby).
Jeśli najwyższy bit jest mniejszy od długości maski (np. liczba = 64, czyli ktoryBit() zwraca 7, a maska ma długość 8) - to wyświetlamy komunikat i nic nie robimy.

1

Ta, straszna skomplikowana funkcja, przeczytać rozdział operacje bitowe i świczyć:

uint64_t maskowanie(unsigned N,unsigned M,unsigned P)
  {
   uint64_t ret=0,msk=1;
   msk=((msk<<N)-1)<<M;
   for(N+=M;P--;ret|=msk) msk<<=N;
   return ret;
  }
3

Ponieważ jesteś leniwy dam Ci rozwiązanie drugiego zadania, które do niczego Ci się nie przyda. Ale jest ciekawe.

Otóż na x86 jest taka instrukcja bsr czyli bit scan reverse. Zwraca ona indeks najwyższego ustawionego bitu. (Jeżeli nie ma żadnych bitów, to jest undefined) Oczywiście ludzie liczą bity od zera, ale wymaganie w zadaniu jest, żeby liczyć od 1. Czyli 0 będzie oznaczało, że nie ma żadnych bitów.

inline std::size_t ktoryBitHeHe(std::uint32_t value) {
  if (value > 0) {
  	return _bit_scan_reverse(value) + 1;
  } else {
  	return 0;
  }
}

http://ideone.com/Cgh0r9

0

Dziękuje Panowie !
Jeśli jeszcze można - Zastanawia mnie teraz druga funkcja, do której jednak niechciałbym uzywać wyżej podanej opcji.
Z jakiego warunku powinienem skorzystać przy przesuwaniu bitów w prawo?

0

Warunku przy przesuwaniu?
Może zacznij od przeczytania pierwszych kilku rozdziałów byle kursu, przynajmniej po to by móc zadać sensowne pytanie.

0
std::size_t ktoryBitHaHa(std::uint32_t value) {
  uint32_t result = 0;
  while (value > 0) {
    value >>= 1;
    ++result;
  }
  return result;
}
0

Zastanawiam się czy to nie będzie średnio szybsze:

std::size_t ktoryBitMath(std::uint32_t value) { return (std::size_t)std::log2((double)value); }

1 użytkowników online, w tym zalogowanych: 0, gości: 1