Algorytm konwersji liczby z systemu binarnego na szesnastkowy
Przeanalizujmy zadanie polegające na konwersji liczb z systemu dwójkowegdwójkowy system pozycyjnydwójkowego na szesnastkowyszesnastkowy system pozycyjnyszesnastkowy i zaimplementujmy realizujący je algorytm w języku Java.
Ważne!
W systemie o podstawie 16, oprócz cyfr z zakresu <0, 9>, dysponujemy także literami od A do F. Tabela prezentuje ich wartości dziesiętne.
Symbol
Wartość
A
10
B
11
C
12
D
13
E
14
F
15
Przykład 1
Naszym zadaniem jest przekonwertowanie liczby binarnej 10010101 na system szesnastkowy.
Gdybyśmy mieli do dyspozycji kartkę i długopis, najpierw przeprowadzilibyśmy konwersję z systemu binarnego na dziesiętny, a następnie na notację szesnastkową. Wyglądałoby to następująco:
Aby przekonwertować liczbę z systemu dwójkowego do systemu dziesiętnego, obliczamy sumę iloczynów wszystkich cyfr danej liczby i odpowiadających im wag (czyli w przypadku systemu binarnego kolejnych potęg liczby 2). Możemy w tym celu zastosować również schemat HorneraPZ4e2fNo0schemat Hornera.
Oto wynik końcowy pierwszej konwersji:
Otrzymany wynik konwertujemy następnie do systemu docelowego, czyli szesnastkowego.
R1Ql17oFZDo7s
Ilustracja przedstawia konwersje liczb dziesiętnych na hexadecymalne. Po lewej stronie prostej znajduje się liczba dziesiętna 149, po prawej reszta z dzielenia przez 16 czyli 5. Poniżej 149 znajduje się liczba ile razy 16 zmieściło się w liczbie 149 czyli 9. Reszta z 9 przez 16 do 9.
Przeanalizujmy listę kroków algorytmu (liczbaDec oznacza liczbę, którą chcemy zamienić na system szesnastkowy):
Weź liczbaDec i podziel ją całkowicie przez podstawę systemu docelowego, czyli 16. W pokazanym wyżej przykładzie bierzemy liczbę 149 i dzielimy ją całkowicie przez 16.
Zapisz wynik reszty z dzielenia całkowitego z kroku 1. Reszta z dzielenia całkowitego 149 przez 16 to 5.
Zapisz wynik dzielenia całkowitego z kroku 1. do zmiennej liczbaDec. Wynik dzielenia całkowitego 149 przez 16 to 9.
Powtarzaj kroki 1‑3, aż do osiągnięcia przez liczbaDec wartości 0. Kolejne dzielenie całkowite, które zostanie wykonane, to 9 przez 16, reszta z tego dzielenia to 9, a wynik dzielenia całkowitego to 0, co kończy powtarzanie dzielenia.
Wynikiem jest liczba szesnastkowa, składająca się z reszt z dzielenia zapisanych od końca. W naszym przykładzie jest to liczba 95.
Oto wynik zadania:
Realizacja algorytmu w języku Java
Przejdźmy do implementacji przedstawionego algorytmu w języku Java. Program będzie wykonywał następujące operacje:
pobranie liczby binarnej z klawiatury,
przekształcenie liczby binarnej na dziesiętną – do tego celu użyjemy wbudowanej funkcji parseInt(),
przekształcenie liczby dziesiętnej na szesnastkową za pomocą funkcji dec2Hex(), którą napiszemy,
wypisanie wyniku.
Zacznijmy od głównej funkcji programu:
Linia 1. public static void main otwórz nawias okrągły String otwórz nawias kwadratowy zamknij nawias kwadratowy args zamknij nawias okrągły otwórz nawias klamrowy.
Linia 2. Scanner sc znak równości new Scanner otwórz nawias okrągły System kropka in zamknij nawias okrągły średnik.
Linia 3. String liczbaBin znak równości sc kropka next otwórz nawias okrągły zamknij nawias okrągły średnik.
Linia 4. if otwórz nawias okrągły liczbaBin kropka length otwórz nawias okrągły zamknij nawias okrągły otwórz nawias ostrokątny 32 zamknij nawias okrągły otwórz nawias klamrowy.
Linia 5. int liczbaDec znak równości Integer kropka parseInt otwórz nawias okrągły liczbaBin przecinek 2 zamknij nawias okrągły średnik.
Linia 6. System kropka out kropka println otwórz nawias okrągły dec2Hex otwórz nawias okrągły liczbaDec zamknij nawias okrągły zamknij nawias okrągły średnik.
Linia 7. zamknij nawias klamrowy else otwórz nawias klamrowy.
Linia 8. System kropka out kropka println otwórz nawias okrągły cudzysłów Podaj liczbę binarną przecinek która zawiera mniej niż 32 bity kropka cudzysłów zamknij nawias okrągły średnik.
Linia 9. zamknij nawias klamrowy.
Linia 10. zamknij nawias klamrowy.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String liczbaBin = sc.next();
if (liczbaBin.length() < 32) {
int liczbaDec = Integer.parseInt(liczbaBin, 2);
System.out.println(dec2Hex(liczbaDec));
} else {
System.out.println("Podaj liczbę binarną, która zawiera mniej niż 32 bity.");
}
}
Konwertowaną liczbę binarną pobieramy z klawiatury i zapisujemy w zmiennej liczbaBin. Zanim użyjemy funkcji parseInt() sprawdzamy, czy podana liczba bitów jest mniejsza od 32, ponieważ wspomniana funkcja ma pewne ograniczenia.
Funkcja ta przyjmuje dwa argumenty: liczbę w postaci ciągu znaków oraz podstawę systemu, w którym zapisana jest liczba. Podana liczba musi zawierać tylko cyfry sytemu podanego jako podstawa. Ponieważ zakres wartości typu Integer to <-2Indeks górny 3131, 2Indeks górny 3131 - 1>, największa liczba binarna, która zostanie poprawnie zamieniona, może składać się z co najwyżej 31 bitów o wartości 1.
W programie używamy więc instrukcji warunkowej, która sprawdza podaną liczbę bitów. Jeżeli jest ich mniej niż 32, liczbę binarną zamieniamy na dziesiętną przy użyciu funkcji parseInt, następnie wywołujemy funkcję Dec2Hex() oraz wypisujemy zwrócony rezultat konwersji. W przeciwnym wypadku wypisujemy stosowny komunikat i kończymy program.
Następny krok to utworzenie funkcji dec2Hex(), która przekształci podaną liczbę dziesiętną na szesnastkową.
Linia 1. public static String dec2Hex otwórz nawias okrągły int liczbaDec zamknij nawias okrągły otwórz nawias klamrowy.
Linia 2. if otwórz nawias okrągły liczbaDec znak równości znak równości 0 zamknij nawias okrągły otwórz nawias klamrowy.
Linia 3. return cudzysłów 0 cudzysłów średnik.
Linia 4. zamknij nawias klamrowy.
Linia 5. String liczbaHex znak równości cudzysłów cudzysłów średnik.
Linia 6. int reszta znak równości 0 średnik.
Linia 8. while otwórz nawias okrągły liczbaDec zamknij nawias ostrokątny 0 zamknij nawias okrągły otwórz nawias klamrowy.
Linia 9. if otwórz nawias okrągły liczbaDec procent 16 otwórz nawias ostrokątny znak równości 9 zamknij nawias okrągły otwórz nawias klamrowy.
Linia 10. reszta znak równości liczbaDec procent 16 średnik.
Linia 11. liczbaHex znak równości reszta plus liczbaHex średnik.
Linia 12. zamknij nawias klamrowy else otwórz nawias klamrowy.
Linia 13. reszta znak równości liczbaDec procent 16 minus 10 plus apostrof A apostrof średnik.
Linia 14. liczbaHex znak równości otwórz nawias okrągły char zamknij nawias okrągły reszta plus liczbaHex średnik.
Linia 15. zamknij nawias klamrowy.
Linia 17. liczbaDec znak równości liczbaDec prawy ukośnik 16 średnik.
Linia 18. zamknij nawias klamrowy.
Linia 20. return liczbaHex średnik.
Linia 21. zamknij nawias klamrowy.
Funkcja zwraca ciąg znaków typu string. Konwersji dokonujemy poprzez dopisywanie („doklejanie”) do zmiennej liczbaHex kolejnych reszt z dzielenia przez 16.
Opis działania funkcji
W linii 2 sprawdzamy, czy konwertowana liczba jest równa 0, jeżeli tak, możemy od razu zwrócić 0 i zakończyć działanie funkcji (linia 3).
W przeciwnym wypadku deklarujemy zmienne:
String liczbaHex = "" – w której zapisany jest wynik końcowy konwersji (linia 5),
int reszta = 0 – która przechowuje reszty z dzielenia przez 16 (linia 6).
Kolejny krok to wywołanie w linii 8. pętli while, która wykonuje instrukcje dopóty, dopóki liczba_dec jest większa od 0.
W linii 9. sprawdzamy, czy reszta z dzielenia przez 16 zawiera się w przedziale <0, 9>. Jeżeli warunek jest spełniony, w linii 10. zapisujemy wynik operacji liczba_dec % 16 do zmiennej reszta, po czym w linii 11. dopisujemy („doklejamy”) go do liczbaHex.
W przeciwnym wypadku w linii 13 do zmiennej reszta wpisujemy wynik operacji liczba_dec % 16 - 10 + A. Odejmując 10 i dodając A, spowodujemy, że w zmiennej reszta będą mogły się znajdować jedynie kody ASCII znaków od A do F.
Następnie w linii 14. wykonujemy rzutowanie zmiennej reszta, która jest liczbą całkowitą, na typ char. W wyniku tej operacji liczba zapisana w zmiennej reszta zmienia się w odpowiadający jej znak z tablicy ASCII. Następnie zmienną reszta doklejamy do liczbaHex.
Zgodnie z algorytmem w 17 linii funkcji wykonujemy dzielenie całkowite zmiennej liczbaDec przez podstawę systemu.
Linia 1. liczbaDec znak równości liczbaDec prawy ukośnik 16 średnik.
liczbaDec = liczbaDec / 16;
Na końcu w linii 20. zwracamy wynik – jest on zapisany w zmiennej liczbaHex.
Poniżej kod całego programu zawierający omówioną funkcję:
Linia 1. import java kropka util kropka Scanner średnik.
Linia 3. public class binary2hexadecimal otwórz nawias klamrowy.
Linia 5. public static String dec2Hex otwórz nawias okrągły int liczbaDec zamknij nawias okrągły otwórz nawias klamrowy.
Linia 6. if otwórz nawias okrągły liczbaDec znak równości znak równości 0 zamknij nawias okrągły otwórz nawias klamrowy.
Linia 7. return cudzysłów 0 cudzysłów średnik.
Linia 8. zamknij nawias klamrowy.
Linia 9. String liczbaHex znak równości cudzysłów cudzysłów średnik.
Linia 10. int reszta znak równości 0 średnik.
Linia 12. while otwórz nawias okrągły liczbaDec zamknij nawias ostrokątny 0 zamknij nawias okrągły otwórz nawias klamrowy.
Linia 13. if otwórz nawias okrągły liczbaDec procent 16 otwórz nawias ostrokątny znak równości 9 zamknij nawias okrągły otwórz nawias klamrowy.
Linia 14. reszta znak równości liczbaDec procent 16 średnik.
Linia 15. liczbaHex znak równości reszta plus liczbaHex średnik.
Linia 16. zamknij nawias klamrowy else otwórz nawias klamrowy.
Linia 17. reszta znak równości liczbaDec procent 16 minus 10 plus apostrof A apostrof średnik.
Linia 18. liczbaHex znak równości otwórz nawias okrągły char zamknij nawias okrągły reszta plus liczbaHex średnik.
Linia 19. zamknij nawias klamrowy.
Linia 21. liczbaDec znak równości liczbaDec prawy ukośnik 16 średnik.
Linia 22. zamknij nawias klamrowy.
Linia 24. return liczbaHex średnik.
Linia 25. zamknij nawias klamrowy.
Linia 28. public static void main otwórz nawias okrągły String otwórz nawias kwadratowy zamknij nawias kwadratowy args zamknij nawias okrągły otwórz nawias klamrowy.
Linia 29. Scanner sc znak równości new Scanner otwórz nawias okrągły System kropka in zamknij nawias okrągły średnik.
Linia 30. String liczbaBin znak równości sc kropka next otwórz nawias okrągły zamknij nawias okrągły średnik.
Linia 31. if otwórz nawias okrągły liczbaBin kropka length otwórz nawias okrągły zamknij nawias okrągły otwórz nawias ostrokątny 32 zamknij nawias okrągły otwórz nawias klamrowy.
Linia 32. int liczbaDec znak równości Integer kropka parseInt otwórz nawias okrągły liczbaBin przecinek 2 zamknij nawias okrągły średnik.
Linia 33. System kropka out kropka println otwórz nawias okrągły dec2Hex otwórz nawias okrągły liczbaDec zamknij nawias okrągły zamknij nawias okrągły średnik.
Linia 34. zamknij nawias klamrowy else otwórz nawias klamrowy.
Linia 35. System kropka out kropka println otwórz nawias okrągły cudzysłów Podaj liczbę binarną przecinek która zawiera mniej niż 32 bity kropka cudzysłów zamknij nawias okrągły średnik.
Linia 36. zamknij nawias klamrowy.
Linia 37. zamknij nawias klamrowy.
Linia 38. zamknij nawias klamrowy.
import java.util.Scanner;
public class binary2hexadecimal {
public static String dec2Hex(int liczbaDec) {
if (liczbaDec == 0) {
return "0";
}
String liczbaHex = "";
int reszta = 0;
while (liczbaDec > 0) {
if (liczbaDec % 16 <= 9) {
reszta = liczbaDec % 16;
liczbaHex = reszta + liczbaHex;
} else {
reszta = liczbaDec % 16 - 10 + 'A';
liczbaHex = (char) reszta + liczbaHex;
}
liczbaDec = liczbaDec / 16;
}
return liczbaHex;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String liczbaBin = sc.next();
if (liczbaBin.length() < 32) {
int liczbaDec = Integer.parseInt(liczbaBin, 2);
System.out.println(dec2Hex(liczbaDec));
} else {
System.out.println("Podaj liczbę binarną, która zawiera mniej niż 32 bity.");
}
}
}
W przedstawionym programie wykorzystaliśmy gotową wbudowaną funkcję parseInt(), która może posłużyć do zamiany liczby binarnej zawierającej nie więcej niż 31 bitów na liczbę dziesiętną. W filmie zamieszczonym w sekcji „Prezentacja multimedialna” zaprezentowane jest rozwiązanie oparte na schemacie Hornera pozbawione omówionych ograniczeń funkcji parseInt().
Słownik
dwójkowy system pozycyjny
dwójkowy system pozycyjny
pozycyjny system zapisu liczb, którego podstawą jest liczba 2 - w zapisie tym występują wyłącznie cyfry 0 oraz 1
szesnastkowy system pozycyjny
szesnastkowy system pozycyjny
pozycyjny system zapisu liczb, którego podstawą jest liczba 16 – w zapisie tym oprócz cyfr od 0 do 9 występują jeszcze znaki A, B, C, D, E, F, oznaczające odpowiednio cyfry od 10 do 15