ś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^3 + 0 * 2^2 + 1 * 2^1 + 1 * 2^0 = 8 + 0 + 2 + 1 = 11_10$.
  3. Przykład HEX -> DEC: `A1_16` = $10 * 16^1 + 1 * 16^0 = 160 + 1 = 161_10$. (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^4 = 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 2026Zadanie 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_2 = 1*2^2 + 0*2^1 + 1*2^0 = 5_10$).
  • **DEC -> Any**: Dzielenie przez podstawę i zbieranie reszt *od końca*.
  • **BIN <-> HEX**: Szybka konwersja przez grupowanie bitów po 4 ($2^4 = 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