średniAlgorytmyPythonC++

Konwersja Systemów Liczbowych (Binarny, Dziesiętny, Szesnastkowy)

20 min czytania
Python, C++
Zaktualizowano: 4.11.2025

Systemy liczbowe to fundament informatyki. Na co dzień używamy systemu dziesiętnego (DEC), opartego na 10 cyfrach (0-9). Komputery wewnątrz działają wyłącznie na systemie binarnym (BIN), czyli na dwóch cyfrach (0 i 1). Z kolei system szesnastkowy (HEX), oparty na 16 symbolach (0-9 oraz A-F), jest używany przez programistów jako wygodny 'skrót' do zapisu długich ciągów binarnych (np. do opisu kolorów, #FF0000, lub adresów pamięci). Zrozumienie, jak te systemy działają i jak płynnie przeliczać liczby między nimi, to absolutna konieczność, by zrozumieć, co tak naprawdę robi komputer.

Dlaczego to ważne? Na maturze zadania z systemów liczbowych pojawiają się zawsze. Mogą to być zadania 'na papierze', gdzie trzeba ręcznie przeliczyć wartości (jak w zadaniu z XORem), zadania z liczbami binarnymi w plikach tekstowych (np. 'policz, ile liczb ma więcej jedynek niż zer') lub zadania wymagające operacji na bitach. Umiejętność zamiany liczby dziesiętnej na binarną i odwrotnie to podstawa do rozwiązania tych problemów.

Teoria

Każdy system liczbowy opiera się na 'podstawie'. W dziesiętnym podstawą jest 10, w binarnym 2, w szesnastkowym 16. Wartość liczby to suma jej cyfr pomnożonych przez odpowiednie wagi, czyli potęgi podstawy systemu.

Jak to działa?

  1. 1. Dowolny system -> Dziesiętny (DEC): Mnożenie przez wagi.
  2. Przykład BIN -> DEC: 1011_2 = 1 2³ + 0 2² + 1 2¹ + 1 2⁰ = 8 + 0 + 2 + 1 = 11₁0.
  3. Przykład HEX -> DEC: A1_16 = 10 16¹ + 1 16⁰ = 160 + 1 = 161₁0. (Pamiętaj: A=10, B=11, C=12, D=13, E=14, F=15).
  4. Python: int('1011', 2) da 11. int('A1', 16) da 161.
  5. 2. Dziesiętny (DEC) -> Dowolny system: Dzielenie przez podstawę i zbieranie reszt.
  6. Przykład DEC -> BIN (dla 11_10):
  7. 11 // 2 = 5 reszty 1
  8. 5 // 2 = 2 reszty 1
  9. 2 // 2 = 1 reszty 0
  10. 1 // 2 = 0 reszty 1
  11. Czytamy reszty od dołu do góry: 1011_2.
  12. Python: bin(11) da '0b1011'. hex(161) da '0xa1'.
  13. 3. Binarny (BIN) <-> Szesnastkowy (HEX) (Szybka konwersja): Grupowanie po 4 bity.
  14. Każde 4 bity (cyfry binarne) odpowiadają dokładnie jednej cyfrze szesnastkowej (2⁴ = 16).
  15. BIN -> HEX: 1011 | 0001 (grupujemy po 4 od prawej). 1011_2 = 11_10 = B_16. 0001_2 = 1_10 = 1_16. Wynik: B1_16.
  16. HEX -> BIN: B1_16. B_16 = 1011_2. 1_16 = 0001_2 (uzupełniamy do 4 bitów!). Wynik: 10110001_2.

Złożoność: Ręczny algorytm zamiany DEC -> BIN (dzielenie przez 2) ma złożoność O(log n), ponieważ liczba kroków (dzieleń) zależy od liczby bitów, a nie od wartości 'n'. Algorytm BIN -> DEC ma złożoność O(k), gdzie 'k' to liczba cyfr (bitów) w liczbie.

Implementacja

Konwersje w Pythonie (Funkcje wbudowane)

Python
# ---- Z dowolnego systemu NA DZIESIĘTNY ----
# Używamy int(string_liczby, podstawa)

bin_na_dec = int("1011", 2)
print(f"'1011' (bin) to {bin_na_dec} (dec)") # 11

hex_na_dec = int("FF", 16)
print(f"'FF' (hex) to {hex_na_dec} (dec)") # 255

# ---- Z DZIESIĘTNEGO na dowolny system ----
# Używamy bin(), hex(), oct()

dec_na_bin = bin(11)
print(f"11 (dec) to {dec_na_bin}") # '0b1011'

dec_na_hex = hex(255)
print(f"255 (dec) to {dec_na_hex}") # '0xff'

# Jak pozbyć się prefiksów '0b' i '0x'?
print(f"Czysty binarny: {bin(11)[2:]}") # '1011'
print(f"Czysty hex: {hex(255)[2:]}") # 'ff'

Na maturze to jest najszybszy i najlepszy sposób. Funkcja `int(string, podstawa)` jest kluczowa. Pamiętaj, że `bin()` i `hex()` zwracają stringi z prefiksami '0b' i '0x', które można obciąć za pomocą `[2:]`.

Algorytm: Ręczna zamiana DEC -> BIN

Python
def dec_na_bin(n):
    if n == 0:
        return "0"
    
    binarny_str = ""
    liczba = n
    
    while liczba > 0:
        reszta = liczba % 2
        binarny_str += str(reszta)
        liczba = liczba // 2
        
    # Reszty są zbierane od końca, więc musimy odwrócić string
    return binarny_str[::-1]

print(f"11 (dec) to ręcznie {dec_na_bin(11)} (bin)") # 1011

To jest implementacja algorytmu 'dziel i zbieraj reszty'. Używamy pętli `while`, operatora modulo `% 2` (po resztę) i dzielenia całkowitego `// 2` (by skrócić liczbę). Na końcu odwracamy string, bo reszty zbieraliśmy od najmniej znaczącej.

Konwersje w C++ (std::stoi, std::bitset, stringstream)

C++
#include <iostream>
#include <string>
#include <sstream> // dla stringstream (dec na hex)
#include <bitset>  // dla bitset (dec na bin)

using namespace std;

int main() {
    // ---- Z dowolnego systemu NA DZIESIĘTNY ----
    // Używamy stoi(string, nullptr, podstawa)
    string bin_str = "1011";
    int bin_na_dec = stoi(bin_str, nullptr, 2);
    cout << "'1011' (bin) to " << bin_na_dec << " (dec)" << endl; // 11

    string hex_str = "FF";
    int hex_na_dec = stoi(hex_str, nullptr, 16);
    cout << "'FF' (hex) to " << hex_na_dec << " (dec)" << endl; // 255

    // ---- Z DZIESIĘTNEGO na dowolny system ----
    
    // DEC -> BIN (bitset)
    string dec_na_bin = bitset<8>(11).to_string(); // <8> to liczba bitów
    cout << "11 (dec) to " << dec_na_bin << " (bin)" << endl; // 00001011

    // DEC -> HEX (stringstream)
    stringstream ss;
    ss << hex << 255;
    string dec_na_hex = ss.str();
    cout << "255 (dec) to " << dec_na_hex << " (hex)" << endl; // ff

    return 0;
}

W C++ jest to trochę bardziej skomplikowane. Do zamiany `string` na `int` używamy `stoi(str, _, podstawa)` z biblioteki `<string>`. Do zamiany `int` na `string` binarny/szesnastkowy najwygodniej użyć `bitset` (dla bin) lub `stringstream` (dla hex).

Przykładowe Zadania Maturalne

Matura 2027Zadanie Zadanie Typu Maturalnego 1

W pliku 'liczby_binarne.txt' znajduje się 200 liczb binarnych, każda w osobnej linii. Napisz program, który znajdzie i wypisze tę liczbę (w postaci binarnej), która po zamianie na system dziesiętny jest największa.

Wskazówka: Nie musisz implementować algorytmu ręcznie. Wczytaj każdą linię (string) z pliku. Użyj wbudowanej funkcji (w Pythonie int(string, 2)) aby zamienić binarny string na liczbę dziesiętną. Trzymaj w zmiennej 'max_dec' największą dotychczasową wartość dziesiętną oraz w 'max_bin_str' odpowiadający jej string binarny.

Pokaż szkic rozwiązania
1. Otwórz plik 'liczby_binarne.txt' do odczytu.
2. Zainicjuj `max_dec = -1` oraz `max_bin_str = ""`.
3. Dla każdej linii w pliku:
   a. Wczytaj string: `bin_str = linia.strip()`.
   b. Przekonwertuj na liczbę dziesiętną: `dec_val = int(bin_str, 2)`.
   c. Sprawdź: `if dec_val > max_dec:`
   d. `  max_dec = dec_val`
   e. `  max_bin_str = bin_str`
4. Po pętli wypisz `max_bin_str`.
Matura 2023Zadanie 2.4 (Matura Czerwiec 2023)

Oblicz (123_10 XOR 101101_2) XOR 2D_16. Wynik podaj w systemie dziesiętnym.

Wskazówka: To zadanie 'na papierze'. Aby wykonać operacje bitowe XOR, musisz sprowadzić wszystkie trzy liczby do tego samego systemu. Najłatwiej zamienić je wszystkie na system dziesiętny, wykonać operacje XOR (oznaczaną w Pythonie jako ^), a na końcu podać wynik.

Pokaż szkic rozwiązania
1. **Liczba 1: `123_10`**. Jest już w systemie dziesiętnym. Wartość: 123.
2. **Liczba 2: `101101_2`**. Zamiana BIN -> DEC:
   $1*2^5 + 0*2^4 + 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0 = 32 + 0 + 8 + 4 + 0 + 1 = 45_10$.
3. **Liczba 3: `2D_16`**. Zamiana HEX -> DEC:
   $2 * 16^1 + 13 * 16^0 = 32 + 13 = 45_10$. (Pamiętaj: D = 13).
4. **Obliczenia (krok po kroku):**
   a. Pierwszy XOR: `123_10 XOR 45_10`.
   b. `123_10 = 1111011_2`
   c. `45_10  = 0101101_2` (uzupełniamy zerem z przodu)
   d. `1111011 XOR 0101101 = 1010110_2`.
   e. `1010110_2 = 64 + 16 + 4 + 2 = 86_10`.
   f. Drugi XOR: `86_10 XOR 45_10` (bo `2D_16 = 45_10`).
   g. `86_10 = 1010110_2`
   h. `45_10 = 0101101_2`
   i. `1010110 XOR 0101101 = 1111011_2`.
5. **Zamiana wyniku na DEC**:
   `1111011_2 = 64 + 32 + 16 + 8 + 0 + 2 + 1 = 123_10`.
6. **Odpowiedź**: 123.

Częste Błędy

❌ Python: int(1011, 2) zamiast int('1011', 2)

Funkcja int() do konwersji oczekuje stringa (tekstu) jako pierwszego argumentu. Przekazanie jej liczby 1011 (traktowanej jako dziesiętna) spowoduje błąd lub (co gorsza) zły wynik.

Poprawka: Zawsze przekazuj liczbę w innym systemie jako string: int('1011', 2).

❌ Zapominanie o prefiksach 0b i 0x w Pythonie

Funkcje bin() i hex() zwracają stringi z prefiksami, np. '0b1011'. Jeśli spróbujesz użyć tego stringa w dalszych obliczeniach (np. zliczyć jedynki), prefiks będzie przeszkadzał.

Poprawka: Do czystej postaci binarnej/szesnastkowej używaj cięcia: bin(n)[2:] lub hex(n)[2:].

❌ Dec -> Bin: Odwrócenie kolejności reszt

Algorytm n % 2 i n // 2 generuje bity od końca (od najmniej znaczącego do najbardziej). Jeśli po prostu skleisz je po kolei, dostaniesz liczbę 'od tyłu'.

Poprawka: Musisz dodawać reszty na początek budowanego stringa (wynik = str(reszta) + wynik) lub zebrać je w liście i na końcu ją odwrócić (wynik.reverse()).

❌ BIN <-> HEX: Błędne grupowanie

Zamiana A1_16 na 1010 (dla A) i 1 (dla 1). Poprawnie powinno być 1 -> 0001. Musisz dopełniać bity do 4.

Poprawka: Zawsze grupuj po 4 bity, dopełniając zerami z lewej, jeśli trzeba: A_16 -> 1010, 1_16 -> 0001. Łącznie: 10100001_2.

❌ Mylenie cyfr HEX (D vs B)

Częsty błąd 'na papierze' to pomyłka: A=10, B=11, C=12, D=13, E=14, F=15. Łatwo pomylić B z D.

Poprawka: Warto zapisać to sobie na brudnopisie podczas egzaminu. Można też szybko sprawdzić w kalkulatorze systemowym.

Kluczowe Wnioski

  • Trzy kluczowe systemy: Dziesiętny (podstawa 10), Binarny (podstawa 2), Szesnastkowy (podstawa 16, 0-9 i A-F).
  • Any -> DEC: Mnożenie przez potęgi podstawy (np. 101₂ = 12² + 02¹ + 1*2⁰ = 5₁0).
  • DEC -> Any: Dzielenie przez podstawę i zbieranie reszt od końca.
  • BIN <-> HEX: Szybka konwersja przez grupowanie bitów po 4 (2⁴ = 16).
  • W Pythonie int(string, podstawa) to Twój najlepszy przyjaciel (np. int('FF', 16)).
  • W Pythonie bin(n) i hex(n) zwracają stringi z prefiksami 0b i 0x.
  • Zadania maturalne często wymagają konwersji, aby wykonać operacje bitowe (jak XOR).

Najczęściej Zadawane Pytania

❓ Po co nam system szesnastkowy (HEX)?

Jest to wygodny dla człowieka 'skrót' do zapisu długich liczb binarnych. Jeden bajt (8 bitów), np. `10101111`, można zapisać jako dwie cyfry HEX: `AF`. Jest to dużo czytelniejsze. Używa się go powszechnie do zapisu kolorów (np. `#FF0000` to 255-R, 0-G, 0-B) i adresów pamięci.

❓ Jak szybko zamienić `110101_2` na dziesiętny?

Sumuj potęgi dwójki tam, gdzie jest jedynka, licząc od prawej (od $2^0$): $110101_2 = 2^5 + 2^4 + 0 + 2^2 + 0 + 2^0 = 32 + 16 + 4 + 1 = 53$.

❓ Czy na maturze mogę używać wbudowanych funkcji `bin()`, `hex()`, `int(s, 2)`?

Tak. Są to funkcje wbudowane w Pythona i są częścią standardowej biblioteki, która jest dozwolona. Używanie ich jest wręcz zalecane, aby oszczędzać czas (chyba że zadanie wprost każe zaimplementować algorytm konwersji).

❓ Jak w Pythonie przekonwertować liczbę dziesiętną na string binarny bez prefiksu '0b'?

Użyj `bin(liczba)[2:]`. Funkcja `bin()` zwraca string, a `[2:]` to 'cięcie' (slicing), które bierze string od trzeciego znaku (indeks 2) do końca, pomijając pierwsze dwa znaki ('0' i 'b').

Chcesz opanować wszystkie tematy maturalne?

Dołącz do kursu i zyskaj dostęp do interaktywnych lekcji, edytora kodu i setek zadań.

Powiązane Tematy