Dlaczego reprezentacja zmiennoprzecinkowa używa bitu znaku zamiast uzupełnienia 2 do wskazania liczb ujemnych

20

Rozważmy reprezentację punktu stałego, którą można uznać za zdegenerowany przypadek liczby zmiennoprzecinkowej. Całkowicie możliwe jest użycie uzupełnienia 2 dla liczb ujemnych. Ale dlaczego bit znaku jest potrzebny do liczb zmiennoprzecinkowych, czy bity mantysy nie powinny używać uzupełnień 2?

Również dlaczego bity wykładnikowe używają odchylenia zamiast reprezentacji wielkości ze znakiem (podobnej do bitów mantysy) lub reprezentacji uzupełnienia 2?

Aktualizacja: Przepraszam, jeśli nie wyjaśniłem. Szukałem powodu, w jaki sposób kształtowana jest reprezentacja zmiennoprzecinkowa. Jeśli nie ma silnego kompromisu w zakresie wdrażania między alternatywami, to czy ktoś mógłby wyjaśnić historyczne aspekty reprezentacji zmiennoprzecinkowej?

koo
źródło

Odpowiedzi:

7

Uzupełnienie do dwóch ma sens, gdy te dwa byty mają te same „jednostki” i tę samą „szerokość”. Przez szerokość rozumiem, powiedzmy, jeśli dodajesz liczbę bitów N i liczbę bitów M, gdzie N i M są różne, lepiej nie używaj uzupełnienia dwóch. W przypadku liczb zmiennoprzecinkowych mamy problem z jednostkami: jeśli wykładniki są różne, wówczas mentalnie przesuwamy jedną z mantys, a teraz mamy ten sam problem jak poprzednio (z szerokością).

Jeśli chodzi o bity wykładnikowe, to poprzez użycie odchylenia zamiast znaku + wielkości uzyskujemy jeszcze jedną wartość (w przeciwnym razie mielibyśmy +0 i -0). Tutaj uzupełnienie dwóch ma sens przy pomnażaniu lub dzieleniu liczb (od tego czasu dodajemy lub odejmujemy wykładniki), ale nie ma tak dużego sensu podczas dodawania lub odejmowania.

Edycja: Komentator zauważył, że można dodać liczby całkowite dopełniacza o różnej długości za pomocą rozszerzenia znaku. Istnieje również problem z wykryciem przepełnienia, ale można to również naprawić. Podsumowując, prawdopodobnie możesz użyć uzupełnienia do dwóch, jeśli jesteś wystarczająco ostrożny. (Musisz także poradzić sobie z mnożeniem i dzieleniem).

Yuval Filmus
źródło
4
„Jeśli dodajesz liczbę N bitów i liczbę M bitów, gdzie N i M są różne, lepiej nie używać uzupełnienia dwóch” - czy mógłbyś to trochę wyjaśnić? Sądzę, że jest całkowicie możliwe podpisanie rozszerzenia liczby za pomocą reprezentacji uzupełnienia 2 za pomocą jej MSB, np. 4'b1111 rozszerzy się do 5'b11111, a 4'b0111 -> 5'b00111. Czy nie powinno być łatwo dodać to do istniejącego mechanizmu zmiany lufy w ramach arytmetyki zmiennoprzecinkowej?
koo
Dziękuję za Twoją odpowiedź! Zredagowałem to pytanie, aby wyraźniej pytało o to, co sprawia, że ​​obecny zmiennoprzecinkowy.
koo
4

Z Wikipedii:

System dwóch uzupełnień ma tę zaletę, że podstawowe operacje arytmetyczne dodawania, odejmowania i mnożenia są identyczne z tymi dla liczb binarnych bez znaku ...

Uzupełnienie do dwóch jest reprezentacją liczb ujemnych, które akurat są bardzo wygodne. To jest cały powód, aby w ogóle go używać.

Para mantysa-wykładnik jest reprezentacją liczby zmiennoprzecinkowej. W większości przypadków, gdy używasz liczb zmiennoprzecinkowych, nie wykonujesz arytmetyki wyłącznie na mantysie lub wyłącznie na wykładniku wykładniczym.

Kache
źródło
4

Ale dlaczego bit znaku jest niezbędny do liczb zmiennoprzecinkowych

Fałszywe założenie. To nie jest konieczne. Jestem prawie pewien, że spotkałem formaty zmiennoprzecinkowe, które używały uzupełnienia 2 dla mantysy, ale musiałbym wykopać się po nazwy.

Nie jestem specjalistą od analizy numerycznej, ale rozumiem, że podpisanie zera jest dla nich ważne. Prawdopodobnie łatwiej jest nim manipulować niż uzupełnieniem. Było to prawdopodobnie kryterium wyboru dla IEEE-754.

Także dlaczego bity wykładnikowe używają odchylenia zamiast reprezentacji wielkości ze znakiem

Znów jest to coś niepotrzebnego, a niektórzy zrobili coś inaczej.

Jest to reprezentacja, dla której łatwiej jest wykonać implementację sprzętową dla zestawu operacji wykonywanych na wykładnikach (i tutaj nie jest wymagana reprezentacja dla -0).

Jedną z konsekwencji tego wyboru jest to, że możesz użyć porównania liczb całkowitych ze znakiem, aby porównać numer FP, jeśli nie przejmujesz się NaN, co być może było kryterium dla niektórych (fakt, że NaN wymaga specjalnej obsługi, wątpię, by to nie było dla IEEE-754).

AProgrammer
źródło
Podpisane porównania liczb całkowitych uszeregują ujemne liczby FP do tyłu. Aby odpowiednio się uszeregować, niezbędny byłby jakiś format dopełniacza, przy czym dopełniacz prawdopodobnie byłby najlepszy (ujemny to ... 110.1111 ..., a nieskończony po lewej i prawej stronie).
supercat
3
MIL-STD-1750A jest prawdopodobnie najczęściej stosowaną architekturą procesora, która określa dopełniającą się reprezentację zmiennoprzecinkową dwójki. W sekcji 4.1: „Zestaw instrukcji powinien obsługiwać 16-bitowe dane o stałej precyzji z pojedynczym punktem, 32-bitowe dane z podwójną precyzją o stałym punkcie, 32-bitowe dane zmiennoprzecinkowe i 48-bitowe zmiennoprzecinkowe dane o rozszerzonej precyzji w reprezentacji uzupełnienia 2. (Podkreślenie moje) .
njuffa
2

IEEE 754 używa znaku / wielkości, a nie uzupełnienia dwóch lub jednego uzupełnienia.

Uzupełnienie dwóch ma tę wadę, że zakres dodatni i ujemny nie są identyczne. Jeśli wszystkie wzory bitowe są poprawne, to masz liczby x, których nie można łatwo obliczyć -x. To źle. Alternatywą jest to, że istnieją nieprawidłowe wzorce bitów, co również jest złe. W IEEE 754 nie ma niepoprawnych wzorów bitów dla zmiennoprzecinkowych 64 lub 32 bitów, więc nie musisz się tym martwić.

Uzupełnienie jednego dopełniałoby mnożenie / dzielenie bardziej złożone (przy podpisanej wielkości, po prostu xor znaków i traktujesz mantysę jako liczbę bez znaku). Jeśli chodzi o dodawanie i odejmowanie, naprawdę nie chcę myśleć o dodawaniu i odejmowaniu w uzupełnieniu, powoduje to ból głowy.

gnasher729
źródło
Pierwszy akapit tej odpowiedzi sugeruje, że znak / wielkość nie ma żadnych wad. Znak / jasność ma +/- 0 i bardziej skomplikowaną arytmetykę niż uzupełnienie do dwóch.
Praxeolitic
Posiadanie +/- zera jest zarówno problemem, jak i cechą. Na przykład podzielenie małej liczby x przez 10 ^ 100 da +0 lub -0, zachowując znak x.
gnasher729,
1

Po podpisaniu zer daje większą ekspresję, co może być przydatne w obliczeniach numerycznych. Strona wikipedii „ Podpisano zero ” mówi:

Twierdzi się, że włączenie podpisanego zera do IEEE 754 znacznie ułatwia osiągnięcie dokładności numerycznej w niektórych krytycznych problemach , w szczególności podczas obliczania złożonych funkcji elementarnych .

WH Kahan, jeden z głównych projektantów zmiennoprzecinkowych IEEE 754, jest z tych powodów zwolennikiem podpisania zera. Jego opinia prawdopodobnie będzie miała dużą wagę.

equaeghe
źródło
1

Myślę, że ważne jest, aby zrozumieć, że obliczenia zmiennoprzecinkowe dają wartości przybliżone , a nie dokładne . Oznacza to, że jeśli obliczenia zmiennoprzecinkowe dają zakodowaną wartość X, to reprezentuje to teoretycznie idealną wartość, która prawie na pewno NIE jest X, ale jest w zakresie [X .. X + e) ​​{gdzie „e” to „ machine epsilon ”, tzn. nie ma liczby zmiennoprzecinkowej między X a X + e}. Mówiąc dokładniej, zmiennoprzecinkowe zero reprezentuje idealną liczbę, która prawdopodobnie nie jest dokładnie zerowa, ale która jest zbyt mała, aby reprezentować ją z niezerową wartością zakodowaną w zmiennoprzecinkowym punkcie.

Biorąc pod uwagę, że użycie reprezentacji znak i wielkość jest sposobem na umożliwienie kodowaniu „zapamiętania” dokładnie, po której stronie zera znajduje się idealna wartość, dodatnia lub ujemna. Jest to krytyczne w niektórych złożonych obliczeniach (w sensie „a + bi”) - złożone-> złożone funkcje są często „wielowartościowe”, więc dla prawidłowego obliczenia niezwykle ważne jest zwrócenie uwagi na lokalizację „odcięć gałęzi”. Podpisane zera oznaczają w pewnym sensie lokalizacje cięć gałęzi - obliczenia wykonane po stronie dodatniej będą różnić się od obliczeń po stronie ujemnej.

PMar
źródło
1
Obliczenia zmiennoprzecinkowe dają dokładne wartości. Różnią się one tylko nieznacznie od wartości, które dają matematyczne liczby rzeczywiste. Liczba zmiennoprzecinkowa reprezentuje jedną liczbę, a nie zakres.
gnasher729
0

Większość formatów zmiennoprzecinkowych wykorzystuje fakt, że w systemie binarnym każda niezerowa wartość z nie-minimalnym wykładnikiem będzie miała „1” jako najbardziej znaczący bit mantysy. Zatem w systemie z 23-bitowym polem dla mantysy, mantysy liczb dodatnich nie mieszczą się w zakresie od 0 do 8 388 607, ale zamiast od 8 388,608 do 16 777 215. Mantysy liczb, które mogą być dodatnie, mogą wynosić od -16,777,215 do -8 388 608 i od +8 388,608 do +16,777,215. Podczas gdy dopełnianie dwóch jest najlepszym formatem numerycznym, gdy konieczne jest, aby obliczenia „płynnie” przekraczały zero, nieciągłe zakresy wartości mantysy oznaczają, że obliczenia nie byłyby w stanie działać płynnie w obrębie zera niezależnie od tego, czy używają uzupełnienia dwóch czy czegoś innego .

supercat
źródło