Liczby binarne to najprostszy sposób zapisu danych dla komputera: wszystko sprowadza się do dwóch stanów, 0 i 1. Dla początkujących w programowaniu ten temat jest ważny nie tylko teoretycznie, bo pomaga zrozumieć bity, bajty, operacje bitowe i to, skąd biorą się niektóre dziwne zachowania liczb w kodzie. W tym tekście pokazuję, jak czytać zapis dwójkowy, jak przeliczać go na dziesiętny, gdzie pojawia się w praktyce i na czym najłatwiej się potknąć.
Najważniejsze rzeczy do zapamiętania o zapisie dwójkowym
- W systemie dwójkowym używa się tylko dwóch cyfr: 0 i 1, a pojedyncza cyfra to bit.
- Wartość liczby zależy od pozycji bitu, czyli od kolejnych potęg 2.
- Przeliczanie na dziesiętny jest sumą wag ustawionych jedynek.
- Przeliczanie na binarny robi się najczęściej przez dzielenie przez 2 i zapisywanie reszt.
- W kodzie spotkasz też literały z prefiksem
0b, operacje bitowe i maski. - Najwięcej problemów sprawiają liczby ujemne, ułamki oraz mylenie operatorów logicznych z bitowymi.
Czym jest zapis dwójkowy i dlaczego programiści go używają
W systemie dwójkowym każda pozycja ma tylko dwie możliwości: 0 albo 1. Taki pojedynczy znak to bit, czyli najmniejsza porcja informacji, a osiem bitów tworzy bajt. W praktyce to świetnie pasuje do elektroniki, bo układom łatwiej odróżnić dwa stany niż wiele poziomów napięcia naraz.
Ja zwykle tłumaczę to tak: komputer nie „myśli” w dziesiętnym sensie, tylko przechowuje stan w postaci szeregu prostych decyzji. Dzięki temu 8 bitów daje 256 kombinacji, 16 bitów 65 536, a 32 bity aż 4 294 967 296. To już nie teoria dla teorii, tylko konkretna różnica w pamięci, zakresach typów i sposobie zapisu danych.
Kiedy to zaczyna być intuicyjne, znacznie łatwiej zobaczyć, dlaczego jedna liczba w kodzie może mieć kilka warstw znaczenia. Następny krok to odczytywanie wartości z samego zapisu.
Jak czytać zapis binarny bez zgadywania
Najważniejsza zasada jest prosta: czytamy od prawej do lewej, a każda pozycja oznacza kolejną potęgę 2. Prawy skraj to 2^0, obok 2^1, potem 2^2 i tak dalej. Jeśli na danej pozycji stoi 1, dodajemy jej wagę; jeśli stoi 0, ta pozycja nie wnosi nic do sumy.
| Pozycja od prawej | Waga | Bit w przykładzie 101101
|
|---|---|---|
| 1 | 2^0 = 1 | 1 |
| 2 | 2^1 = 2 | 0 |
| 3 | 2^2 = 4 | 1 |
| 4 | 2^3 = 8 | 1 |
| 5 | 2^4 = 16 | 0 |
| 6 | 2^5 = 32 | 1 |
Wynik jest więc prosty: 32 + 8 + 4 + 1 = 45. Taki przykład dobrze pokazuje, że nie trzeba liczyć każdego bitu z osobna na ślepo. Wystarczy zrozumieć wagę pozycji i od razu widać sens całego zapisu.
Gdy już umiesz odczytać wartość, przeliczenie na drugi system jest tylko kwestią dobrej procedury.
Jak zamieniać między systemem dziesiętnym a dwójkowym
W praktyce są dwie metody, które warto znać od razu: dzielenie przez 2 przy przejściu z dziesiętnego na binarny oraz sumowanie wag przy ruchu w drugą stronę. Obie są proste, tylko trzeba je wykonać dokładnie.
Z dziesiętnego na binarny
Bierzemy liczbę, dzielimy przez 2 i zapisujemy resztę. Potem dzielimy wynik ponownie przez 2, znowu zapisujemy resztę, i tak dalej aż dojdziemy do zera. Reszty czytamy od dołu do góry.
| Dzielenie | Iloraz | Reszta |
|---|---|---|
| 45 / 2 | 22 | 1 |
| 22 / 2 | 11 | 0 |
| 11 / 2 | 5 | 1 |
| 5 / 2 | 2 | 1 |
| 2 / 2 | 1 | 0 |
| 1 / 2 | 0 | 1 |
Po odczytaniu reszt od końca dostajesz 101101. Ja polecam ćwiczyć to właśnie na liczbach typu 13, 27, 45 albo 128, bo szybko widać wzór i nie trzeba walczyć z długimi ciągami cyfr.
Z binarnego na dziesiętny
Tu działa prosta reguła: zaczynasz od zera, a potem dla każdej kolejnej cyfry mnożysz poprzedni wynik przez 2 i dodajesz bieżący bit. To wygodna forma schematu Hornera, ale nie musisz znać nazwy, żeby z niej korzystać.
101101
0 → 1 → 2 → 5 → 11 → 22 → 45
W kodzie często zobaczysz też zapis z prefiksem 0b, na przykład 0b101101. W wielu językach programowania taki zapis od razu mówi interpreterowi lub kompilatorowi, że chodzi o liczbę w systemie dwójkowym. Jeśli chcesz przeliczyć ją z powrotem, możesz użyć funkcji podobnej do parseInt("101101", 2) albo wbudowanego zamiennika właściwego dla danego języka.
Po tej stronie wszystko jest już mechaniczne, a to otwiera drogę do tego, co w praktyce robi najwięcej zamieszania: operacji na bitach.
Jak komputer liczy na bitach i co to zmienia w kodzie
Dodawanie w systemie dwójkowym wygląda znajomo, ale ma jedną kluczową różnicę: 1 + 1 daje 10, czyli zapis z przeniesieniem. To dokładnie ten sam mechanizm, który znasz z dodawania w dziesiętnym, tylko przeniesienie pojawia się częściej, bo mamy mniej możliwych cyfr.
1011
+ 0011
= 1110
W programowaniu przydają się też operacje bitowe, czyli działania wykonywane na pojedynczych bitach. Najczęściej spotkasz:
| Operator | Znaczenie | Przykład |
|---|---|---|
& |
AND, oba bity muszą być równe 1 | 1010 & 1100 = 1000 |
| |
OR, wystarczy jeden bit równy 1 | 1010 | 0101 = 1111 |
^ |
XOR, 1 tylko wtedy, gdy bity są różne | 1010 ^ 1111 = 0101 |
~ |
NOT, odwrócenie bitów | zmienia 0 na 1 i odwrotnie |
<< |
przesunięcie w lewo | często odpowiada mnożeniu przez 2 |
>> |
przesunięcie w prawo | często odpowiada dzieleniu przez 2 |
To nie są tylko sztuczki z podręcznika. Maski bitowe, flagi, przełączniki uprawnień i szybkie sprawdzanie cech danych nadal pojawiają się w realnym kodzie. Gdy to rozumiesz, łatwiej czytać fragmenty, które dla innych wyglądają jak przypadkowy ciąg zer i jedynek.
Skoro fundament jest już jasny, można przejść od teorii do miejsca, w którym te zasady naprawdę pracują w web developmencie.Gdzie zapis dwójkowy pojawia się w web developmentie
Na pierwszym planie nie zawsze widać bity, ale one są pod spodem niemal wszędzie. Wystarczy spojrzeć na pamięć, kodowanie znaków, transmisję danych, kompresję albo operacje na obrazach. Właśnie dlatego temat nie jest „szkolną ciekawostką”, tylko elementem, który porządkuje myślenie o danych.
W praktyce najbardziej przydają mi się trzy obszary: flagi, rozmiary danych i zapis kolorów. Kolory w CSS zapisujesz zwykle w szesnastkach, ale heksadecymalny format jest wygodny właśnie dlatego, że każda cyfra odwzorowuje 4 bity. Dla oka człowieka to dużo czytelniejsze niż długi ciąg zer i jedynek.
| Obszar | Dlaczego to ma związek z binarnym zapisem | Praktyczny przykład |
|---|---|---|
| Flagi i uprawnienia | Jeden bit oznacza stan włączony albo wyłączony | odznaczenie opcji, dostęp do funkcji, tryb debug |
| Maski bitowe | Pozwalają ustawiać i sprawdzać pojedyncze cechy | sprawdzenie, czy dana flaga jest aktywna |
| Rozmiary danych | 8 bitów to 1 bajt, a liczba bitów wpływa na zakres wartości | 8 bitów = 256 możliwości, 32 bity = 4 294 967 296 |
| Kolory i media | Hex i binarny zapis opisują te same wartości w innej skali |
#FFAA00 jako wygodniejszy zapis niż surowe bity |
To właśnie dlatego w kursach programowania warto nie uciekać od bitów zbyt wcześnie. Im lepiej rozumiesz, co dzieje się pod spodem, tym łatwiej diagnozujesz błędy i czytasz dokumentację bez zgadywania. Następny krok to kilka pułapek, które potrafią zmylić nawet osoby po pierwszych ćwiczeniach.
Na czym najczęściej wykładają się początkujący
Sama idea jest prosta, ale kilka szczegółów potrafi zamieszać w głowie. Ja zwykle zwracam uwagę na cztery rzeczy: liczby ujemne, ułamki, kolejność czytania i mylenie operacji bitowych z logicznymi.
Liczby ujemne
W pamięci komputera liczby ze znakiem nie są zazwyczaj zapisywane po prostu jako „minus plus bity”. Najczęściej używa się uzupełnienia do 2, bo upraszcza dodawanie i odejmowanie sprzętowe. To ważne, ale na poziomie podstaw nie musisz od razu liczyć wszystkiego ręcznie; wystarczy wiedzieć, że minus w kodzie maszynowym działa inaczej niż na kartce.
Ułamki
W zapisie dwójkowym część ułamkowa istnieje, ale niektóre liczby dziesiętne nie mają w nim skończonego odpowiednika. Najbardziej znany problem to wartości typu 0,1: w wielu implementacjach ich reprezentacja jest przybliżona, co później widać jako drobne błędy zaokrągleń. To jeden z powodów, dla których w finansach trzeba uważać bardziej niż w prostych obliczeniach technicznych.
Przeczytaj również: Złożoność obliczeniowa - Czy Twój kod skaluje się dobrze?
Drobne pomyłki w zapisie
- Mylenie kierunku czytania - wartość liczysz od prawej strony, nie od lewej.
-
Ignorowanie zer wiodących -
00001010i1010to ta sama wartość, ale inna długość zapisu. -
Łączenie pojęć - operator bitowy
&to nie to samo co logiczne&&, a|nie jest tym samym co||. -
Zapominanie o prefiksie - w kodzie
0balbo podobny zapis ułatwia odróżnienie systemu liczbowego.
Jeśli te pułapki masz z tyłu głowy, nauka robi się dużo spokojniejsza. Zostaje jeszcze jedna rzecz: jak ćwiczyć, żeby temat naprawdę został w pamięci, a nie tylko „wyglądał znajomo” przez jeden wieczór.
Jak utrwalić ten temat bez wkuwania na siłę
Najlepiej działa krótka, powtarzalna praktyka. Nie próbuję uczyć się wszystkich działań naraz; biorę kilka liczb, przeliczam je w obie strony i sprawdzam wynik w kodzie albo kalkulatorze. Po kilku takich rundach wzorzec zaczyna być oczywisty.
- Przelicz ręcznie liczby 5, 10, 13, 27 i 45.
- Zapisz w kodzie jedną wartość jako
0b...i sprawdź, jak program ją odczytuje. - Dodaj dwie liczby binarne na kartce, żeby zobaczyć przeniesienia.
- Sprawdź jedną maskę bitową i jedno przesunięcie o 1 pozycję w lewo.
- Powiąż zapis binarny z czymś realnym, na przykład z bajtem, kolorem albo flagą ustawień.
Jeżeli chcesz iść dalej, naturalnym następnym krokiem są właśnie maski bitowe oraz zapis szesnastkowy, bo w praktyce bardzo często pracują razem. To dobry moment, żeby zacząć patrzeć na dane nie jak na „magiczne liczby”, tylko jak na uporządkowane zbiory prostych stanów.