O.4 -- Konwersja liczb całkowitych pomiędzy reprezentacją binarną i dziesiętną

Rozważ dziesiętną wartość całkowitą, taką jak 5623. Intuicyjnie rozumiemy, że te cyfry oznaczają (5 * 1000) + (6 * 100) + (2 * 10) + (3 * 1). Ponieważ jest 10 liczb dziesiętnych, wartość każdej kolejnej cyfry po lewej stronie zwiększa się 10-krotnie.

Liczby binarne działają w ten sam sposób, z tą różnicą, że są tylko 2 cyfry binarne (0 i 1), więc wartość każdej cyfry zwiększa się 2-krotnie. Podobnie jak przecinki są często używane, aby ułatwić odczytanie dużej liczby dziesiętnej (np. 1 427 435), często piszemy liczby binarne w grupy po 4 bity, aby ułatwić ich odczytanie (np. 1101 0101).

Poniższa tabela liczy do 15 w systemie dziesiętnym i binarnym:

Wartość dziesiętnaWartość binarna
00
11
210
311
4100
5101
6110
7111
81000
91001
101010
111011
121100
131101
141110
151111

Konwersja binarna na dziesiętną

W poniższych przykładach zakładamy, że mamy do czynienia z liczbą bez znaku liczby całkowite.

Rozważ 8-bitową (1 bajt) liczbę binarną 0101 1110. Binarna liczba 0101 1110 oznacza (0 * 128) + (1 * 64) + (0 * 32) + (1 * 16) + (1 * 8) + (1 * 4) + (1 * 2) + (0 * 1). Jeśli podsumujemy wszystkie te części, otrzymamy liczbę dziesiętną 64 + 16 + 8 + 4 + 2 = 94.

Oto ten sam proces w formie tabeli. Mnożymy każdą cyfrę binarną przez jej wartość cyfrową (określoną przez jej pozycję). Sumując wszystkie te wartości otrzymujemy sumę.

Konwersja 0101 1110 na dziesiętny:

Cyfra binarna0  1  0  1  1  1  1  0  
* Wartość cyfry1286432168421
= Razem (94)0640168420

Przeliczmy 1001 0111 na dziesiętne:

Cyfra binarna1  0  0  1  0  1  1  1  
* Wartość cyfry1286432168421
= Suma (151)12800160421

1001 0111 dwójkowa = 151 w postaci dziesiętnej.

Można to łatwo rozszerzyć do 16 lub 32-bitowych liczb binarnych, po prostu dodając więcej kolumn. Pamiętaj, że najłatwiej jest zacząć od prawej strony i kierować się w lewo, mnożąc wartość cyfry przez 2.

Metoda 1 konwersji postaci dziesiętnej na binarną

Konwersja z postaci dziesiętnej na binarną jest nieco trudniejsza, ale wciąż całkiem prosta. Jest na to kilka dobrych metod.

W tej pierwszej metodzie stale dzielisz przez 2, a resztę zapisujesz. Liczbę binarną konstruuje się na końcu z reszt, od dołu do góry.

Konwersja 148 z postaci dziesiętnej na binarną (używając r do oznaczenia reszty):

148 / 2 = 74 r0
74 / 2 = 37 r0
37 / 2 = 18 r1
18 / 2 = 9 r0
9 / 2 = 4 r1
4 / 2 = 2 r0
2 / 2 = 1 r0
1 / 2 = 0 r1

Zapisywanie wszystkich pozostałych od dołu do góry: 1001 0100

148 dziesiętne = 1001 0100 binarne.

Możesz zweryfikować tę odpowiedź, konwertując liczbę binarną z powrotem na dziesiętną:

(1 * 128) + (0 * 64) + (0 * 32) + (1 * 16) + (0 * 8) + (1 * 4) + (0 * 2) + (0 * 1) = 148

Ta metoda jest najlepsza dla ludzi, ponieważ wymaga tylko dzielenia przez 2. Jest mniej dobra dla maszyn, ponieważ wymaga przechowywania wszystkich bitów w miarę ich obliczania, aby można je było wydrukować później odwróć kolejność.

Metoda 2 konwersji liczby dziesiętnej na binarną

W pozostałych dwóch metodach będziemy pracować dalej, obliczając każdy bit w miarę upływu czasu, tak że nie będziemy musieli na końcu rekonstruować liczby binarnej.

Rozważmy ponownie liczbę dziesiętną 148. Największa potęga liczby 2 mniejsza niż 148 to 128, więc zaczniemy od tego.

Czy 148 >= 128? Tak, więc 128 bitów musi wynosić 1. 148 - 128 = 20, co oznacza, że ​​musimy znaleźć bity warte o 20 więcej.
Czy 20 >= 64? Nie, więc 64 bity muszą mieć wartość 0.
Czy 20 >= 32? Nie, więc 32 bity muszą mieć wartość 0.
Czy 20 >= 16? Tak, więc 16 bitów musi wynosić 1. 20 - 16 = 4, co oznacza, że ​​musimy znaleźć bity warte o 4 więcej.

Czy 4 >= 8? Nie, więc 8 bitów musi wynosić 0.
Czy 4 >= 4? Tak, więc 4 bity muszą wynosić 1. 4 - 4 = 0, co oznacza, że ​​wszystkie pozostałe bity muszą wynosić 0.

148 = (1 * 128) + (0 * 64) + (0 * 32) + (1 * 16) + (0 * 8) + (1 * 4) + (0 * 2) + (0 * 1) = 1001 0100

W formacie tabeli:

Liczba binarna1  0  0  1  0  1  0  0  
* Wartość cyfry1286432168421
= Razem (148)12800160400

Ta metoda jest dość łatwa dla ludzi, gdy liczby są małe (np. dla 8-bitowych liczb binarnych). Jest to również dość wydajne w przypadku maszyn, ponieważ każdy bit wymaga porównania, odjęcia i przypisania.

Metoda 3 konwersji liczby dziesiętnej na binarną

Ta metoda jest wariantem metody 2, która wykorzystuje dzielenie liczb całkowitych. Consider the decimal number 148 yet again. Największa potęga liczby 2, która jest mniejsza niż 148, to 128, więc od tego zaczniemy.

148 / 128 = 1 z pewną resztą. Ponieważ 1 jest nieparzyste, ten bit ma wartość 1.
148 / 64 = 2 z pewną resztą. Ponieważ 2 jest parzyste, ten bit wynosi 0.
148 / 32 = 4 z pewną resztą. Ponieważ 4 jest parzyste, ten bit wynosi 0.
148 / 16 = 9 z pewną resztą. Ponieważ 9 jest nieparzyste, ten bit ma wartość 1.
148 / 8 = 18 z pewną resztą. Ponieważ 18 jest parzyste, ten bit wynosi 0.
148 / 4 = 37 z pewną resztą. Ponieważ 37 jest nieparzyste, ten bit to 1.
148 / 2 = 74 z pewną resztą. Ponieważ 74 jest parzyste, ten bit wynosi 0.
148 / 1 = 148 z pewną resztą. Ponieważ 148 jest parzyste, tym bitem jest 0.

148 = (1 * 128) + (0 * 64) + (0 * 32) + (1 * 16) + (0 * 8) + (1 * 4) + (0 * 2) + (0 * 1) = 1001 0100

Ta metoda nie jest dobra dla ludzi, ponieważ wymaga dużo dzielenia. Jest również mniej wydajny w przypadku maszyn, ponieważ dzielenie jest operacją nieefektywną. Ale łatwo jest to napisać w kodzie, ponieważ nie wymaga instrukcji if.

Kolejny przykład

Przekonwertujmy 117 na binarną metodą 1:

117 / 2 = 58 r1
58 / 2 = 29 r0
29 / 2 = 14 r1
14 / 2 = 7 r0
7 / 2 = 3 r1
3 / 2 = 1 r1
1 / 2 = 0 r1

Konstruowanie liczby z reszt od dołu do góry, 117 = 111 0101 binarny

I metodą 2:

Największa potęga 2 mniejsza niż 117 to 64.

Czy 117 >= 64? Tak, więc 64-bitowy musi wynosić 1. 117 - 64 = 53.
Czy 53 >= 32? Tak, więc 32-bitowy musi wynosić 1. 53 - 32 = 21.
Czy 21 >= 16? Tak, więc 16 bitów musi wynosić 1. 21 - 16 = 5.

Czy 5 >= 8? No, so the 8 bit must be 0.
Is 5 >= 4? Tak, więc 4 bity muszą wynosić 1. 5 - 4 = 1.
Czy 1 >= 2? No, so the 2 bit must be 0.
Is 1 >= 1? Tak, więc 1 bit musi wynosić 1.

117 dziesiętnych = 111 0101 binarnych.

Dodawanie binarne

W niektórych przypadkach (za chwilę się o tym przekonamy) przydatna jest możliwość dodania dwóch liczb binarnych. Dodawanie liczb binarnych jest zaskakująco łatwe (może nawet łatwiejsze niż dodawanie liczb dziesiętnych), chociaż na początku może wydawać się dziwne, ponieważ nie jesteś do tego przyzwyczajony.

Rozważ dwie małe liczby binarne:
0110 (6 w systemie dziesiętnym) +
0111 (7 w systemie dziesiętnym)

Dodajmy je. First, line them up, as we have above. Następnie zaczynając od prawej i kończąc na lewej, dodajemy każdą kolumnę cyfr, tak jak to robimy w przypadku liczby dziesiętnej. Ponieważ jednak cyfrą binarną może być tylko 0 lub 1, są tylko 4 możliwości:

  • 0 + 0 = 0
  • 0 + 1 = 1
  • 1 + 0 = 1
  • 1 + 1 = 0, przenieś 1 do następnej kolumny

Zróbmy pierwszą kolumnę:

0110 (6 in decimal) +
0111 (7 in decimal)
----
   1

0 + 1 = 1. Łatwe.

Druga kolumna:

 1
0110 (6 in decimal) +
0111 (7 in decimal)
----
  01

1 + 1 = 0, z przeniesieniem 1 do następnej kolumny

Trzecia kolumna:

11
0110 (6 in decimal) +
0111 (7 in decimal)
----
 101

To jest trochę trudniejsze. Zwykle 1 + 1 = 0, z jedynką przenoszoną do następnej kolumny. Jednakże mamy już 1 przeniesioną z poprzedniej kolumny, więc musimy dodać 1. W ten sposób otrzymamy 1 w tej kolumnie, a 1 zostanie przeniesione do następnej kolumny.

Ostatnia kolumna:

11
0110 (6 in decimal) +
0111 (7 in decimal)
----
1101

0 + 0 = 0, ale jest przeniesiona 1, więc dodajemy 1. 1101 = 13 w systemie dziesiętnym.

Teraz, jak dodać 1 do dowolnej liczby binarnej (takiej jak 1011 0011)? Podobnie jak powyżej, tylko dolna liczba jest binarna 1.

      11  (carry column)
1011 0011 (original binary number)
0000 0001 (1 in binary)
---------
1011 0100

Liczby ze znakiem i uzupełnienie do dwójki

W powyższych przykładach zajmowaliśmy się wyłącznie liczbami całkowitymi bez znaku. W tej sekcji przyjrzymy się, jak traktowane są liczby ze znakiem (które mogą być ujemne).

Liczby całkowite ze znakiem są zwykle przechowywane przy użyciu metody znanej jako uzupełnienie do dwóch. W uzupełnieniu do dwójki bit znajdujący się najbardziej na lewo (najbardziej znaczący) jest używany jako bit znaku. Bit znaku 0 oznacza, że liczba jest dodatnia (lub zero), a bit znaku 1 oznacza, że liczba jest ujemna.

Liczby ze znakiem dodatnim są reprezentowane w postaci binarnej, podobnie jak liczby dodatnie bez znaku (z bitem znaku ustawionym na 0).

Liczby ze znakiem ujemnym są przedstawiane w systemie binarnym jako bitowa odwrotność liczby dodatniej plus 1.

Konwersja liczby dziesiętnej na binarną (dwójki uzupełnienie)

Na przykład, oto jak reprezentujemy -5 w binarnym uzupełnieniu do dwójki:

Najpierw ustalamy binarną reprezentację dla 5: 0000 0101
Następnie odwracamy wszystkie bity: 1111 1010
Następnie dodajemy 1:1111 1011

Konwersja -76 na binarny:

Dodatnie 76 w binarnym: 0100 1100
Odwróć wszystkie bity: 1011 0011
Dodaj 1: 1011 0100

Dlaczego dodajemy 1? Rozważmy liczbę 0. Jeśli wartość ujemna byłaby po prostu przedstawiona jako odwrotność liczby dodatniej (tzw. „dopełnienie do jedynki”), 0 miałoby dwie reprezentacje: 0000 0000 (zero dodatnie) i 1111 1111 (zero ujemne). Dodanie 1 powoduje celowe przepełnienie liczby 1111 1111 i uzyskanie wartości 0000 0000. Zapobiega to dwóm reprezentacjom 0 i upraszcza część wewnętrznej logiki potrzebnej do wykonywania arytmetyki na liczbach ujemnych.

Konwersja binarna (dopełnienie do dwóch) na dziesiętną

Aby przekonwertować liczbę binarną z uzupełnieniem do dwóch z powrotem na dziesiętną, najpierw spójrz na bit znaku.

Jeśli bit znaku wynosi 0, po prostu przekonwertuj liczbę, jak pokazano powyżej dla liczb bez znaku.

Jeśli bit znaku wynosi 1, odwracamy bity, dodajemy 1, następnie konwertujemy na liczbę dziesiętną, a następnie ustawiamy liczbę dziesiętną na ujemną (ponieważ bit znaku był pierwotnie ujemny).

Na przykład, aby przekonwertować 1001 1110 z uzupełnienia do dwójki na liczba dziesiętna:
Podane: 1001 1110
Odwróć bity: 0110 0001
Dodaj 1: 0110 0010
Zamień na dziesiętny: (0 * 128) + (1 * 64) + (1 * 32) + (0 * 16) + (0 * 8) + (0 * 4) + (1 * 2) + (0 * 1) = 64 + 32 + 2 = 98
Ponieważ pierwotny bit znaku był ujemny, ostateczna wartość wynosi -98.

Istnieje inna metoda, którą łatwiej jest obliczyć ręcznie. W tej metodzie bit znaku reprezentuje wartość ujemną, wszystkie pozostałe bity reprezentują wartości dodatnie.

Podane: 1001 1110
Przelicz na dziesiętny: (1 * -128) + (0 * 64) + (0 * 32) + (1 * 16) + (1 * 8) + (1 * 4) + (1 * 2) + (0 * 1) = -128 + 16 + 8 + 4 + 2 = -98

Dlaczego typy mają znaczenie

Rozważ wartość binarną 1011 0100. Jaką wartość to reprezentuje? Prawdopodobnie powiedziałbyś 180 i gdyby to była liczba binarna bez znaku, miałbyś rację.

Gdyby jednak ta wartość została zapisana przy użyciu uzupełnienia do dwójki, wynosiłaby -76.

A gdyby wartość została zakodowana w inny sposób, mogłaby to być zupełnie inna wartość.

Skąd więc C++ wie, czy wydrukować zmienną zawierającą wartość binarną 1011 0100 jako 180 lub -76?

Jeśli tytuł sekcji tego nie zdradza, tutaj w grę wchodzą typy. Typ zmiennej określa zarówno sposób, w jaki wartość zmiennej jest kodowana do postaci binarnej, jak i dekodowana z powrotem do wartości. Jeśli więc typ zmiennej byłby liczbą całkowitą bez znaku, wiedziałby, że 1011 0100 jest standardowym plikiem binarnym i powinien zostać wydrukowany jako 180. Jeśli zmienna była liczbą całkowitą ze znakiem, wiedziałby, że 1011 0100 zostało zakodowane przy użyciu uzupełnienia do dwóch (teraz gwarantowane od C++ 20) i powinno zostać wydrukowane jako -76.

A co z konwersją liczb zmiennoprzecinkowych z/na binarny?

Sposób konwersji liczb zmiennoprzecinkowych z/na plik binarny jest nieco bardziej skomplikowany i prawdopodobnie nie będziesz musiał się o tym nigdy dowiedzieć. Jeśli jednak jesteś ciekawy, zobacz tę witrynę, która dobrze wyjaśnia szczegółowo temat.

Czas quizu

Pytanie nr 1

Przelicz 0100 1101 na liczbę dziesiętną.

Pokaż rozwiązanie

Pytanie nr 2

Przekonwertuj 93 na 8-bitową liczbę binarną bez znaku, stosując obie metody 1 i 2 powyżej.

Pokaż rozwiązanie

Pytanie nr 3

Przekształć -93 na 8-bitową liczbę binarną ze znakiem (używając uzupełnienia do dwóch).

Pokaż rozwiązanie

Pytanie nr 4

Przekształć 1010 0010 na liczbę dziesiętną bez znaku.

Pokaż rozwiązanie

Pytanie #5

Przelicz 1010 0010 na liczbę dziesiętną ze znakiem (załóż uzupełnienie do dwójki).

Pokaż rozwiązanie

Pytanie nr 6

Napisz program, który poprosi użytkownika o wprowadzenie liczby z zakresu od 0 do 255. Wypisz tę liczbę jako 8-bitową liczbę binarną (w postaci #### ####). Nie używaj żadnych operatorów bitowych. Nie używaj std::bitset.

Pokaż wskazówkę

Pokaż wskazówkę

Przypomnienie: std::uint8_t jest zwykle traktowany jako znak, a nie int. Może to powodować nieoczekiwane zachowanie, gdy jest używane z danymi wejściowymi lub wyjściowymi.

Pokaż rozwiązanie

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
735 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze