System szesnastkowy na dziesiętny
Kodowanie,  Poradnik

System szesnastkowy na dziesiętny

Liczby zapisane w różnych systemach pozycyjnych pojawiają się praktycznie wszędzie tam, gdzie działa elektronika, pamięć komputera, adresowanie danych albo programowanie niskopoziomowe. Programista widzi je w debugerze, administrator w adresach pamięci, a osoba analizująca plik binarny w surowym zapisie bajtów. System szesnastkowy pozwala skrócić długie ciągi bitów do bardziej czytelnej postaci i właśnie dlatego stał się standardem w informatyce. W praktyce bardzo często trzeba wykonać konwersję typu system szesnastkowy na system dziesiętny i poprawnie interpretować wartość liczbową danych zapisanych w pamięci.

Dlaczego system szesnastkowy jest wygodniejszy od binarnego podczas pracy z pamięcią i danymi komputerowymi

System dziesiętny działa na podstawie 10 cyfr: od 0 do 9. Człowiek używa go naturalnie, bo liczenie historycznie oparto o liczbę palców dłoni. Komputery działają jednak binarnie, czyli wykorzystują dwa stany: 0 oraz 1.

Problem pojawia się wtedy, gdy liczby binarne stają się bardzo długie. Przykładowo:

ZapisWartość
11111111255
111111111111111165535
111111111111111111111111111111114294967295

Odczytywanie takich wartości jest niewygodne i łatwo popełnić błąd. Dlatego wprowadzono zapis szesnastkowy.

System szesnastkowy korzysta z podstawy 16. Oznacza to, że jedna pozycja może przyjąć 16 wartości:

DziesiętnieHex
00
11
22
33
44
55
66
77
88
99
10A
11B
12C
13D
14E
15F

Każda cyfra hex odpowiada dokładnie 4 bitom. To kluczowa zależność.

BinarnieHex
00000
00011
00102
00113
01004
01015
01106
01117
10008
10019
1010A
1011B
1100C
1101D
1110E
1111F

Dzięki temu liczba:

BinarnieHex
11111111FF
10101010AA
11001100CC

W praktyce debugowanie pamięci z użyciem hex jest wielokrotnie prostsze niż analiza binarna. Wystarczy spojrzeć na zrzut pamięci w debuggerze, żeby zobaczyć adresy typu:

Adres
0x7FFE12A0
0x0040FFAA
0xDEADBEEF

Taki zapis jest krótszy, czytelniejszy i łatwiejszy do grupowania.

System szesnastkowy na dziesiętny podczas ręcznego przeliczania wartości krok po kroku

Konwersja polega na wykorzystaniu potęg liczby 16.

Każda pozycja liczby ma swoją wagę:

PozycjaWaga
016⁰
116¹
216²
316³
416⁴

Przykład liczby:

HexPozycja
22
A1
30

Liczba to:

2162+10161+31602\cdot16^2+10\cdot16^1+3\cdot16^02⋅162+10⋅161+3⋅160

Rozpisanie:

ElementObliczenieWynik
2 × 16²2 × 256512
A × 16¹10 × 16160
3 × 16⁰3 × 13

Suma:

Wynik
675

Czyli:

HexDziesiętnie
2A3675

Bardzo częsty błąd polega na czytaniu liczby od lewej strony bez uwzględnienia wag pozycji. W systemach pozycyjnych pozycja cyfry ma znaczenie większe niż sama wartość cyfry.

Przykład:

HexBłędne rozumowaniePoprawna wartość
FF15 + 15255

Poprawne obliczenie:

15161+1516015\cdot16^1+15\cdot16^015⋅161+15⋅160

ElementWynik
15 × 16240
15 × 115
Suma255

Przy większych liczbach widać wyraźnie, dlaczego potęgi są istotne.

Przykład:

HexPozycje
1F42,1,0

Obliczenia:

1162+15161+41601\cdot16^2+15\cdot16^1+4\cdot16^01⋅162+15⋅161+4⋅160

SkładnikWynik
1 × 256256
15 × 16240
4 × 14
Suma500

Wynik końcowy:

HexDziesiętnie
1F4500

To właśnie dlatego w analizie pamięci liczba 0xFF oznacza 255, a nie 30.

Znaczenie potęg liczby 16 i zależności między systemem binarnym oraz heksadecymalnym

System hex nie istnieje samodzielnie. Jest bezpośrednio związany z binarnym.

Każde 4 bity tworzą jedną cyfrę hex.

Przykład:

BinarnieGrupowanieHex
101011111010 1111AF

Teraz można policzyć wartość dziesiętną.

HexDziesiętnie
A10
F15

Obliczenie:

10161+1516010\cdot16^1+15\cdot16^010⋅161+15⋅160

Wynik
175

Sprawdzenie binarne:

BitWartość
1128
064
132
016
18
14
12
11

Suma:

Wynik
175

W praktyce oznacza to, że programista może bardzo szybko przechodzić pomiędzy reprezentacją binarną a hex bez wykonywania pełnych obliczeń dziesiętnych.

W architekturze komputerów jest to ogromna oszczędność czasu. Adres:

Hex
0xFFFFFFFF

to po prostu:

Binarnie
11111111111111111111111111111111

czyli maksymalna wartość 32-bitowa bez znaku:

Dziesiętnie
4294967295

Takie liczby pojawiają się stale przy pracy z:

  • wskaźnikami pamięci,
  • adresami procesora,
  • rejestrami CPU,
  • analizą pakietów sieciowych,
  • kolorami RGB,
  • kodowaniem znaków,
  • assemblerem,
  • sterownikami urządzeń.

System szesnastkowy na dziesiętny w programowaniu oraz podczas pracy z pamięcią operacyjną

W większości języków programowania liczby hex zapisuje się z prefiksem 0x.

JęzykPrzykład
C0xFF
C++0x1A
Python0xABC
PHP0x10

Program wykonuje konwersję automatycznie.

Tabela przykładów:

JęzykKod
Cprintf("%d", 0xFF);
C++cout << 0xFF;
Pythonprint(0xFF)
PHPecho 0xFF;

Wynik:

Wartość
255

Konwersja ręczna w Pythonie:

Kod
x = "2A"
print(int(x, 16))

Wynik:

Wynik
42

Przykład w C:

Kod
#include <stdio.h>
int main()
{
int x = 0x2A;
printf("%d\n", x);
return 0;
}

Wynik:

Wynik
42

Przykład w C++:

Kod
#include <iostream>
using namespace std;
int main()
{
int x = 0x2A;
cout << x << endl;
}

Przykład w PHP:

Kod
<?php
$x = hexdec("2A");
echo $x;
?>

W praktyce problem pojawia się wtedy, gdy ktoś nie rozumie różnicy między reprezentacją a wartością.

Przykład:

ZapisZnaczenie
255liczba dziesiętna
0xFFta sama liczba w hex
11111111ta sama liczba binarnie

To nie są trzy różne liczby. To trzy sposoby zapisu tej samej wartości.

W analizie błędów programów takie nieporozumienie potrafi kosztować wiele godzin. Szczególnie przy pracy z pamięcią lub protokołami sieciowymi.

Najczęstsze błędy podczas konwersji liczb heksadecymalnych oraz problemy pojawiające się przy dużych wartościach

Pierwszy problem to błędne interpretowanie liter.

LiteraWartość
A10
B11
C12
D13
E14
F15

Osoby początkujące często próbują traktować litery jako tekst, a nie cyfry systemu liczbowego.

Drugi problem to pomijanie pozycji.

Przykład:

HexBłędny wynik
100100

Poprawne obliczenie:

1162+0161+01601\cdot16^2+0\cdot16^1+0\cdot16^01⋅162+0⋅161+0⋅160

Wynik
256

Kolejny problem pojawia się przy liczbach ujemnych zapisanych w kodzie uzupełnień do dwóch.

Przykład 8-bitowy:

HexBinarnie
FF11111111

Bez znaku:

InterpretacjaWartość
unsigned255

Ze znakiem:

InterpretacjaWartość
signed int8-1

To bardzo ważne w C i C++, gdzie typ danych wpływa na interpretację tych samych bitów.

Przykład:

Kod
unsigned char a = 0xFF;
signed char b = 0xFF;

Tabela wyników:

ZmiennaWynik
a255
b-1

Błędy tego typu często prowadzą do:

  • przepełnień,
  • błędów pamięci,
  • niepoprawnych obliczeń,
  • błędów sieciowych,
  • uszkodzenia danych binarnych.

Przy analizie protokołów komunikacyjnych jest to szczególnie niebezpieczne.

Gdzie konwersja liczb szesnastkowych pojawia się realnie w systemach operacyjnych, sieciach i elektronice

Adres MAC:

MAC
00:1A:2B:3C:4D:5E

Każda para znaków to jeden bajt zapisany hex.

Kolory HTML:

KolorHex
czerwony#FF0000
zielony#00FF00
niebieski#0000FF

Kolor #FFFFFF:

255164+255162+255255\cdot16^4+255\cdot16^2+255255⋅164+255⋅162+255

oznacza maksymalną jasność wszystkich kanałów RGB.

W debugerach procesów można spotkać adresy:

Adres
0x7FF61A20
0x00401000

W logach systemowych bardzo często pojawiają się kody błędów:

Kod
0x80070005
0xC0000005

Programista analizujący crash dump musi rozumieć takie wartości natychmiast, bez używania kalkulatora.

W mikrokontrolerach hex jest praktycznie standardem.

Przykład konfiguracji rejestru:

Kod
PORTB = 0xFF;

oznacza ustawienie wszystkich 8 bitów portu na 1.

W sieciach komputerowych analiza pakietów w Wiresharku również opiera się o zapis szesnastkowy. Jeden błędnie odczytany bajt potrafi całkowicie zmienić interpretację danych.

FAQ dotyczące konwersji liczb szesnastkowych i interpretacji zapisu heksadecymalnego

Czy liczba hex zawsze zaczyna się od 0x

Nie. Prefiks 0x jest tylko konwencją używaną w wielu językach programowania. Sama liczba może być zapisana również jako FF, 2A albo ABC123.

Dlaczego system szesnastkowy ma akurat 16 znaków

Ponieważ 16 jest potęgą liczby 2.

16=2416=2^416=24

Dzięki temu jedna cyfra hex odpowiada dokładnie 4 bitom.

Czy można konwertować bardzo duże liczby hex ręcznie

Można, ale staje się to niewygodne. Przy liczbach 64-bitowych lub 128-bitowych zwykle używa się narzędzi programistycznych albo kalkulatorów programistycznych.

Dlaczego programiści wolą hex zamiast binarnego

Hex jest dużo krótszy i łatwiejszy do odczytu. Jednocześnie zachowuje bezpośrednie powiązanie z bitami.

Czy zapis dziesiętny jest dokładniejszy od hex

Nie. To tylko inna reprezentacja tej samej wartości.

Czy każdą liczbę dziesiętną można zapisać hex

Tak. Każdą liczbę całkowitą można zapisać w dowolnym systemie pozycyjnym.

Dlaczego w assemblerze i debuggerach wszędzie widać hex

Ponieważ sprzęt komputerowy operuje na bitach i bajtach. Hex najlepiej odwzorowuje strukturę pamięci.

Konwersja między systemami liczbowymi jest jedną z tych rzeczy, które początkowo wyglądają jak szkolne ćwiczenie matematyczne, a później okazują się podstawową umiejętnością przy analizie pamięci, debugowaniu programów i pracy z elektroniką. Bez rozumienia zapisu heksadecymalnego trudno wygodnie pracować z niskopoziomową informatyką, protokołami komunikacyjnymi albo architekturą komputerów.

Źródło Foto: Freepik

Dodaj komentarz