Jak przechowywane są wartości ze znakiem ujemnym?

13

Oglądałem ten film na maksymalnych i minimalnych wartościach liczb całkowitych ze znakiem.

Weźmy przykład dodatniej wartości ze znakiem - 0000 0001 Pierwszy bit oznacza, że ​​liczba jest dodatnia, a ostatnie 7 bitów to sama liczba. Można to łatwo zinterpretować jako +1.

Teraz weźmy przykład ujemnej wartości ze znakiem - 1000 0000, która wychodzi na -8. Ok, komputer może zrozumieć, że jest to wartość ujemna z powodu pierwszego bitu, ale jak, do diabła, rozumie, że 000 0000 oznacza -8?

Ogólnie, w jaki sposób przechowywane / interpretowane na komputerze wartości ze znakiem ujemnym są przechowywane?

dyskutowane drzewo
źródło
nl.wikipedia.org/wiki/Two%27s_complement to sposób przechowywania liczb binarnych na komputerach.
Pieter B
@PieterB Może twój komputer. I wielu innych ludzi. Z dobrych powodów! Ale nie sugeruj, że to jedyny sposób.
underscore_d
Jak lubisz. Mogę wymyślić co najmniej 256! sposoby przechowywania (8 bitów) liczb binarnych na komputerach. Jednak większość z nich jest niesamowicie głupia.
Caleth
C nie określa, w dużej mierze decyduje producent chipów o reprezentacji danych. C zostaje skompilowany z kodem maszynowym i należy uważać, aby nie zdefiniować na nowo sposobu przechowywania liczb przez układ. Te same zasady dotyczą liczb zmiennoprzecinkowych. Producent chipów decyduje, w jaki sposób są one przechowywane. Większość producentów układów wykorzystuje uzupełnienie 2, ale jestem pewien, że są wyjątki.
Berin Loritsch,

Odpowiedzi:

29

Standard C nie nakazuje żadnego konkretnego sposobu reprezentowania liczb ujemnych.

W większości implementacji, które mogą wystąpić, liczby całkowite ze znakiem ujemnym są przechowywane w tak zwanym uzupełnieniu do dwóch . Innym ważnym sposobem przechowywania liczb ujemnych jest uzupełnienie .

Uzupełnienie dwóch liczb N-bitowych xjest zdefiniowane jako 2^N - x. Na przykład, uzupełnieniem dwójki 8-bit 1jest 2^8 - 1, lub 1111 1111. Uzupełnienie dwóch 8-bitowych 8to 2^8 - 8, co jest w formacie binarnym 1111 1000. Można to również obliczyć, odwracając bity xi dodając jeden. Na przykład:

 1      = 0000 0001
~1      = 1111 1110
~1 + 1  = 1111 1111
-1      = 1111 1111

 21     = 0001 0101
~21     = 1110 1010
~21 + 1 = 1110 1011
-21     = 1110 1011

Uzupełnienie jednej liczby N-bitowej x jest zdefiniowane jako x, a wszystkie bity są odwrócone.

 1      = 0000 0001
-1      = 1111 1110

 21     = 0001 0101
-21     = 1110 1010

Uzupełnienie dwóch ma kilka zalet w stosunku do uzupełnienia jednego. Na przykład nie ma pojęcia „ujemnego zera”, co z wielu powodów jest mylące dla wielu osób. Dodawanie, mnożenie i odejmowanie działają tak samo z podpisanymi liczbami całkowitymi zaimplementowanymi z uzupełnieniem do dwóch, podobnie jak w przypadku liczb całkowitych bez znaku.

Miles Rout
źródło
19

Istnieją trzy dobrze znane metody reprezentowania wartości ujemnych w formacie binarnym:

  1. Podpisana wielkość . Jest to najłatwiejszy do zrozumienia, ponieważ działa tak samo jak do tej pory, gdy mamy do czynienia z ujemnymi wartościami dziesiętnymi: pierwsza pozycja (bit) reprezentuje znak (0 dla wartości dodatniej, 1 dla wartości ujemnej), a pozostałe bity reprezentują liczbę . Chociaż łatwo jest nam to zrozumieć, trudno jest pracować z komputerami, zwłaszcza gdy wykonujemy arytmetykę z liczbami ujemnymi.
    W 8-bitowej wielkości ze znakiem wartość 8 jest reprezentowana jako 0 0001000, a -8 jako 1 0001000.

  2. Uzupełnienie . W tej reprezentacji liczby ujemne są tworzone z odpowiedniej liczby dodatniej przez odwrócenie wszystkich bitów, a nie tylko bitu znakowego. Ułatwia to pracę z liczbami ujemnymi dla komputera, ale ma tę komplikację, że istnieją dwie różne reprezentacje dla +0 i -0. Przerzucanie wszystkich bitów sprawia, że ​​jest to trudniejsze do zrozumienia dla ludzi.
    W uzupełnieniu 8-bitowym wartość 8 jest reprezentowana jako 00001000, a -8 jako 11110111.

  3. Uzupełnienie dwóch . Jest to najczęstsza reprezentacja stosowana obecnie w przypadku liczb całkowitych ujemnych, ponieważ jest najłatwiejsza do pracy z komputerami, ale jest również najtrudniejsza do zrozumienia dla ludzi. Porównując wzorce bitów stosowane dla wartości ujemnych między uzupełnieniem jednego i drugiego, można zaobserwować, że ten sam wzór bitowy w uzupełnieniu dwóch koduje kolejną niższą liczbę. Na przykład 11111111 oznacza -0 w uzupełnieniu jednego i -1 w uzupełnieniu dwóch i podobnie dla 10000000 (-127 vs -128).
    W uzupełnieniu 8-bitowych dwóch wartość 8 jest reprezentowana jako 00001000, a -8 jako 11111000.

Bart van Ingen Schenau
źródło
8
Podpisana wielkość ma również dwa zera.
Jörg W Mittag
+1 za wzmiankę o znaku / wielkości. nietypowe i niewygodne (dla procesorów, jeśli nie ludzi!), ale warte poznania.
underscore_d
Prawie wszyscy pracujemy z podpisaną wielkością, szczególnie z numerami FP.
Paulo1205
2

Podpisane liczby całkowite są przechowywane przy użyciu http://en.wikipedia.org/wiki/Two%27s%20complement

Następnie otrzymujesz:

000   0
001   1
010   2
011   3
100   -4
101   -3
110   -2
111   -1

Zasadniczo jest to bardzo łatwe liczenie, liczysz do połowy maksymalnej liczby całkowitej ze znakiem. Zrób +1, uczyń go ujemnym i zacznij odliczać.

Pieter B.
źródło