Podobnie jak większość wyjaśnień, które widziałem, powyższe wyjaśniają, jak pracować z uzupełnieniem 2, ale tak naprawdę nie wyjaśniają, czym są matematyczne. Spróbuję to zrobić, przynajmniej dla liczb całkowitych, i omówię tło, które prawdopodobnie jest najpierw znane.
Przypomnij sobie, jak to działa w przypadku liczb dziesiętnych:
2345
to sposób pisania
2 × 10 3 + 3 × 10 2 + 4 × 10 1 + 5 × 10 0 .
W ten sam sposób, binarny jest sposobem pisania liczb przy użyciu tylko 0 i 1 zgodnie z tym samym ogólnym pomysłem, ale zastępując te 10 powyżej 2s. Następnie w formacie binarnym
1111
jest sposobem na napisanie
1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0,
a jeśli się uda, okaże się, że wynosi 15 (podstawa 10). To dlatego, że jest to
8 + 4 + 2 + 1 = 15.
To wszystko dobrze i dobrze dla liczb dodatnich. Działa nawet w przypadku liczb ujemnych, jeśli chcesz po prostu umieścić przed nimi znak minus, tak jak ludzie robią to z liczbami dziesiętnymi. Można to zrobić nawet na komputerach, ale nie widziałem takiego komputera od wczesnych lat siedemdziesiątych. Zostawię powody innej dyskusji.
W przypadku komputerów bardziej wydajne jest stosowanie reprezentacji uzupełnienia dla liczb ujemnych. A oto coś, co często jest pomijane. Notacje dopełniające obejmują pewnego rodzaju odwrócenie cyfr liczby, nawet implikowanych zer poprzedzających normalną liczbę dodatnią. To niezręczne, ponieważ powstaje pytanie: wszystkie? Może to być nieskończona liczba cyfr, które należy wziąć pod uwagę.
Na szczęście komputery nie reprezentują nieskończoności. Liczby są ograniczone do określonej długości (lub szerokości, jeśli wolisz). Wróćmy więc do dodatnich liczb binarnych, ale o określonym rozmiarze. W tych przykładach użyję 8 cyfr („bitów”). Nasz numer binarny to tak naprawdę
00001111
lub
0 × 2 7 + 0 × 2 6 + 0 × 2 5 + 0 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0
Aby utworzyć ujemne uzupełnienie 2, najpierw uzupełniamy wszystkie (binarne) cyfry, tworząc
11110000,
i dodajemy 1, tworząc
11110001,
ale jak mamy to rozumieć jako -15?
Odpowiedź brzmi: zmieniamy znaczenie bitu wyższego rzędu (skrajnie lewy). Ten bit będzie wynosił 1 dla wszystkich liczb ujemnych. Zmiana polegać będzie na zmianie znaku jego udziału w wartości liczby, w której się pojawia. Teraz nasz 11110001 jest rozumiany jako
- 1 × 2 7 + 1 × 2 6 + 1 × 2 5 + 1 × 2 4 + 0 × 2 3 + 0 × 2 2 + 0 × 2 1 + 1 × 2 0
Zauważ, że „-” przed tym wyrażeniem? Oznacza to, że bit znaku ma ciężar -2 7 , czyli -128 (podstawa 10). Wszystkie pozostałe pozycje zachowują tę samą wagę, co w liczbach binarnych bez znaku.
Wypracowanie naszego -15 to
-128 + 64 + 32 + 16 + 1
Wypróbuj na swoim kalkulatorze. jest -15.
Spośród trzech głównych sposobów, w jakie widziałem liczby ujemne reprezentowane w komputerach, dopełnienie 2 wygrywa zdecydowanie dla wygody w ogólnym użyciu. Ma jednak dziwność. Ponieważ jest binarny, musi istnieć parzysta liczba możliwych kombinacji bitów. Każdą liczbę dodatnią można powiązać z jej ujemną, ale jest tylko jedno zero. Negowanie zera daje zero. Jest jeszcze jedna kombinacja, liczba z 1 w bicie znaku i 0 wszędzie indziej. Odpowiednia liczba dodatnia nie pasowałaby do liczby używanych bitów.
Jeszcze bardziej dziwne w tej liczbie jest to, że jeśli spróbujesz uformować liczbę dodatnią, uzupełniając ją i dodając, otrzymujesz z powrotem tę samą liczbę ujemną. Wydaje się naturalne, że zero by to zrobiło, ale jest to nieoczekiwane i wcale nie jest to zachowanie, do którego jesteśmy przyzwyczajeni, ponieważ poza komputerami, ogólnie myślimy o nieograniczonej podaży cyfr, a nie o arytmetyki o stałej długości.
To jest jak wierzchołek góry lodowej osobliwości. Pod powierzchnią czeka jeszcze więcej, ale to wystarczy na tę dyskusję. Prawdopodobnie można znaleźć więcej, badając „przepełnienie” arytmetyki stałoprzecinkowej. Jeśli naprawdę chcesz się w to zaangażować, możesz także zbadać „arytmetykę modułową”.