Przejdź do głównej zawartości

[C++]Konwersja systemu dziesiętnego na binarny [dec2bin, dec2u2]

Konwersja między systemami liczbowymi była już poruszana w tym serwisie tym razem zajmę się kodem U2. Inaczej zwany uzupełnieniem do 2. Opis tego systemu pojawił się w kontekście wstępu do programowania w języku Python [tutaj].

Prosty program tzw. szkolny zamiany nieujemnej liczby dziesiętnej na jej postać binarną:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;

int main() {

 int liczba;
 cin >> liczba;
 
 string wynik;
 
 while(liczba){
  wynik = (liczba%2?"1":"0") + wynik;
  liczba /= 2;
 }
 cout << wynik;

 return 0;
}

Poniżej prezentuję kod programu, który zawiera trzy metody rozwiązania problemu jakim jest wyświetlenie użytkownikowi reprezentacji u2 podanej przez niego liczby dziesiętnej.

Pierwsza z nich wywodzi się z typowego algorytmu konwersji systemu dec do u2:
1. przedstaw bezwzględną wartość liczby dziesiętnej w postaci binarnej,
2. dodaj na początek tak powstałego ciągu zer i jedynek 0,
3. jeżeli liczba podana przez użytkownika jest ujemna zaneguj wszystkie bity i dodaj algebraicznie 1 do tak powstałej liczby binarnej,
4. jeżeli chcesz przedstawić liczbę na większej ilości bitów powiel pierwszy znak na początku tego ciągu aż uzyskasz pożądaną długość reprezentacji.

Z wrodzonego lenistwa - nie chciałem implementować dodawania liczb w systemie binarnym - dodaję 1 do liczby gdy tylko stwierdzę, że jest ona ujemna. Robię to na początku czyli mój algorytm wygląda następująco

1. jeżeli liczba jest ujemna dodaj do niej 1
2. przedstaw bezwzględną wartość liczby dziesiętnej w postaci binarnej (tutaj również korzystam z tego, że dla działania modulo nieistotny jest znak liczby dzielonej)
3. dodaj na początek tak powstałego ciągu zer i jedynek 0
4. jeżeli liczba podana przez użytkownika jest ujemna zaneguj wszystkie bity,
5. jeżeli chcesz przedstawić liczbę na większej ilości bitów powiel pierwszy znak na początku tego ciągu aż uzyskasz pożądaną długość reprezentacji.

Druga metoda korzysta z tego, że w pamięci komputera zmienne typu int przechowywane są już w postaci u2. Wystarczy tylko je odczytać. Do tego celu użyłem iloczynu bitowego & oraz przesunięcia bitowego (zamiast niego można użyć funkcji potęgującej). Algorytm w tym przypadku wygląda następująco:

wykonaj 32 razy (int w kompilatorze 32bitowym ma długość 32 bitów):
1. sprawdzaj wynik iloczynu bitowego między liczbą podaną przez użytkownika i odpowiednią potęgą dwójki (tylko jedna jedynka w reprezentacji) począwszy od 31 a kończąc na 0.
2. jeżeli iloczyn jest różny od zera to wypisz 1 w przeciwnym razie wypisz 0.

Trzecia metoda jest najprostsza ale należy pamiętać o tym, że istnieje coś takiego jak bitset. Gdy rzutujemy na ten typ dowolną liczbę całkowita dostajemy jej reprezentację w systemie u2. W ostrych nawiasach (<>) podaje się długość reprezentacji. By skorzystać z tej metody trzeba dołączyć bibliotekę bitset do programu.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <bitset>
using namespace std;

int main() {
 int liczba;
 cin >> liczba;
// dec2u2 metoda 1 - dzielenie modulo i negacja 
 string licz;
 int tmp = liczba;
 int tmp2;
 
 if (liczba<0)
  tmp++;
 while(tmp)
 {
  licz = (tmp%2?"1":"0") + licz;
  tmp /=2;
 }
 licz = "0" + licz;
 if (liczba<0)
 {
  for(int i=0;i<licz.size(); i++)
   licz[i] = (licz[i]=='1'?'0':'1');
 }
 tmp2 = licz.size();
 for(int i=0;i<32-tmp2;i++) 
  licz = licz[i]+licz;
 
 cout << licz << endl;
 
// dec2u2 - meoda 2 - odczyt stanu bitów w pamięci
 for (int i=31;i>=0; i--){
  cout << (liczba&(1<<i)?1:0);
 }
 
 cout << endl;
// dec2u2 - metoda 3 - wykorzystanie rzutowania na bitset
 cout <<  bitset<32>(liczba);
 
 return 0;
}

Komentarze

Popularne posty z tego bloga

Python - lekcja 005

Spis treści - zamiana całkowitych liczb dziesiętnych na ich odpowiedniki w innych systemach liczbowych (algorytm), - ujemne liczby całkowite w systemie binarnym (ZM, U1, U2, algorytm, formatowanie stringów, rzutowanie ze zmianą systemu liczbowego) [dec2bin, dec2ZM, dec2U1, dec2U2] - zadania.