Jaka jest różnica między operacją zmiennoprzecinkową o pojedynczej precyzji a podwójną precyzją?

168

Jaka jest różnica między operacją zmiennoprzecinkową o pojedynczej precyzji a operacją zmiennoprzecinkową o podwójnej precyzji?

Szczególnie interesują mnie kwestie praktyczne związane z konsolami do gier wideo. Na przykład, czy Nintendo 64 ma procesor 64-bitowy, a jeśli tak, czy to znaczy, że jest zdolny do wykonywania operacji zmiennoprzecinkowych o podwójnej precyzji? Czy PS3 i Xbox 360 mogą wykonywać operacje zmiennoprzecinkowe podwójnej precyzji, czy tylko pojedynczą precyzję, a w ogólnym użyciu są wykorzystywane możliwości podwójnej precyzji (jeśli istnieją?).

tweetypi
źródło
17
Fakt, że procesor jest 64-bitowy zwykle oznacza, że ​​procesor ma 64-bitowe rejestry ogólnego przeznaczenia (tj. Liczby całkowite) i rozmiar adresu pamięci . Ale nie mówi nic o matematyce zmiennoprzecinkowej. Na przykład procesory Intel IA-32 są 32-bitowe, ale natywnie obsługują zmiennoprzecinkowe o podwójnej precyzji.
Roman Zavalov

Odpowiedzi:

215

Uwaga: Nintendo 64 ma 64-bitowy procesor, jednak:

Wiele gier wykorzystywało 32-bitowy tryb przetwarzania chipa, ponieważ większa precyzja danych dostępna przy 64-bitowych typach danych nie jest zwykle wymagana w grach 3D, a także fakt, że przetwarzanie 64-bitowych danych zużywa dwa razy więcej pamięci RAM, pamięci podręcznej i przepustowość, zmniejszając w ten sposób ogólną wydajność systemu.

Z Webopedia :

Termin podwójna precyzja jest trochę mylący, ponieważ precyzja nie jest tak naprawdę podwójna.
Słowo double wywodzi się z faktu, że liczba o podwójnej precyzji wykorzystuje dwa razy więcej bitów niż zwykła liczba zmiennoprzecinkowa.
Na przykład, jeśli liczba o pojedynczej precyzji wymaga 32 bitów, jej odpowiednik o podwójnej precyzji będzie miał 64 bity.

Dodatkowe bity zwiększają nie tylko precyzję, ale także zakres wielkości, które można przedstawić.
Dokładna wielkość, o jaką zwiększa się precyzja i zakres wielkości, zależy od formatu używanego przez program do reprezentowania wartości zmiennoprzecinkowych.
Większość komputerów używa standardowego formatu znanego jako format zmiennoprzecinkowy IEEE.

Format podwójnej precyzji IEEE ma w rzeczywistości ponad dwa razy więcej bitów precyzji niż format pojedynczej precyzji, a także znacznie większy zakres.

Ze standardu IEEE dla arytmetyki zmiennoprzecinkowej

Pojedyncza precyzja

Standardowa reprezentacja zmiennoprzecinkowa pojedynczej precyzji IEEE wymaga 32-bitowego słowa, które może być reprezentowane jako ponumerowane od 0 do 31, od lewej do prawej.

  • Pierwszy bit to bit znaku , S,
  • następnych osiem bitów to bity wykładnika , „E” i
  • ostatnie 23 bity to ułamek „F”:

    S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
    0 1      8 9                    31
    

Wartość V reprezentowaną przez słowo można określić następująco:

  • Jeśli E = 255 i F jest różne od zera, to V = NaN („To nie jest liczba”)
  • Jeśli E = 255 i F wynosi zero, a S wynosi 1, to V = -Infinity
  • Jeśli E = 255 i F wynosi zero, a S wynosi 0, to V = nieskończoność
  • Jeśli 0<E<255wtedy, V=(-1)**S * 2 ** (E-127) * (1.F)gdzie „1.F” ma reprezentować liczbę binarną utworzoną przez przedrostek F z niejawną wiodącą 1 i punktem binarnym.
  • Jeśli E = 0 i F jest niezerowe, to V=(-1)**S * 2 ** (-126) * (0.F). Są to wartości „nieznormalizowane”.
  • Jeśli E = 0 i F wynosi zero, a S wynosi 1, to V = -0
  • Jeśli E = 0 i F wynosi zero, a S wynosi 0, to V = 0

W szczególności,

0 00000000 00000000000000000000000 = 0
1 00000000 00000000000000000000000 = -0

0 11111111 00000000000000000000000 = Infinity
1 11111111 00000000000000000000000 = -Infinity

0 11111111 00000100000000000000000 = NaN
1 11111111 00100010001001010101010 = NaN

0 10000000 00000000000000000000000 = +1 * 2**(128-127) * 1.0 = 2
0 10000001 10100000000000000000000 = +1 * 2**(129-127) * 1.101 = 6.5
1 10000001 10100000000000000000000 = -1 * 2**(129-127) * 1.101 = -6.5

0 00000001 00000000000000000000000 = +1 * 2**(1-127) * 1.0 = 2**(-126)
0 00000000 10000000000000000000000 = +1 * 2**(-126) * 0.1 = 2**(-127) 
0 00000000 00000000000000000000001 = +1 * 2**(-126) * 
                                     0.00000000000000000000001 = 
                                     2**(-149)  (Smallest positive value)

Podwójna precyzja

Standardowa reprezentacja zmiennoprzecinkowa podwójnej precyzji IEEE wymaga 64-bitowego słowa, które może być przedstawione jako ponumerowane od 0 do 63, od lewej do prawej.

  • Pierwszy bit to bit znaku , S,
  • następnych jedenaście bitów to bity wykładnika „E” i
  • ostatnie 52 bity to ułamek „F”:

    S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    0 1        11 12                                                63
    

Wartość V reprezentowaną przez słowo można określić następująco:

  • Jeśli E = 2047 i F jest różne od zera, to V = NaN („To nie jest liczba”)
  • Jeśli E = 2047 i F wynosi zero, a S wynosi 1, to V = -Infinity
  • Jeśli E = 2047 i F wynosi zero, a S wynosi 0, to V = nieskończoność
  • Jeśli 0<E<2047wtedy, V=(-1)**S * 2 ** (E-1023) * (1.F)gdzie „1.F” ma reprezentować liczbę binarną utworzoną przez przedrostek F z niejawną wiodącą 1 i punktem binarnym.
  • Jeśli E = 0 i F jest niezerowe, to V=(-1)**S * 2 ** (-1022) * (0.F)są to wartości „nieznormalizowane”.
  • Jeśli E = 0 i F wynosi zero, a S wynosi 1, to V = -0
  • Jeśli E = 0 i F wynosi zero, a S wynosi 0, to V = 0

Odniesienie:
Norma ANSI / IEEE 754-1985,
Standard binarnej arytmetyki zmiennoprzecinkowej.

VonC
źródło
9
Wiem o tym z twojego źródła, ale nie podoba mi się zdanie: „Termin podwójna precyzja jest trochę mylący, ponieważ precyzja nie jest tak naprawdę podwójna”. Precyzja nieocieplane i te dni są dość powszechnie zdefiniowany przez IEEE, a jak podkreślić pojedynczej precyzji ma 23 bitów w ułamku i dwukrotnie posiada 52 bitów - czyli w zasadzie podwojenie precyzję ...
Carl Walsh
5
@ZeroDivide ' **' to potęgowanie
VonC
11
@CarlWalsh 52/23! = 2 ergo to nie jest „podwójna precyzja”
rfoo
@johnson Więcej informacji na temat nieznormalizowanych wartości znajdziesz w easy68k.com/paulrsm/6502/WOZFPPAK.TXT , a także na stackoverflow.com/a/28801033/6309
VonC
2
@rfoo Jeśli chcesz być pedantyczny, pewny, że nie jest dokładnie podwójny, ale 52/2> 23, więc tak, jest to podwójna precyzja, po prostu podwójna, a potem trochę więcej.
JShorthouse
42

Czytałem wiele odpowiedzi, ale żadna nie wydaje się poprawnie wyjaśniać, skąd pochodzi słowo podwójne . Pamiętam bardzo dobre wyjaśnienie, jakiego udzielił mi profesor Uniwersytetu, którego miałem kilka lat temu.

Przypominając styl odpowiedzi VonC, reprezentacja zmiennoprzecinkowa pojedynczej precyzji wykorzystuje słowo 32-bitowe.

  • 1 bit na znak S
  • 8 bitów na wykładnik „E”
  • 24 bity na ułamek , zwany także mantysą lub współczynnikiem (chociaż reprezentowane są tylko 23). Nazwijmy to „M” (w przypadku mantysy wolę tę nazwę, ponieważ „ułamek” może być źle zrozumiany).

Reprezentacja:

          S  EEEEEEEE   MMMMMMMMMMMMMMMMMMMMMMM
bits:    31 30      23 22                     0

(Żeby zaznaczyć, znak jest ostatnim, a nie pierwszym).

Podwójna precyzja floating point reprezentacji używa słowa 64 bitów.

  • 1 bit na znak S
  • 11 bitów na wykładnik „E”
  • 53 bity dla frakcji / mantysy / współczynnika (chociaż reprezentowane są tylko 52), `` M ''

Reprezentacja:

           S  EEEEEEEEEEE   MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
bits:     63 62         52 51                                                  0

Jak możesz zauważyć, napisałem, że mantysa ma w obu typach nieco więcej informacji w porównaniu z jej reprezentacją. W rzeczywistości mantysa jest liczbą reprezentowaną bez jej znaczenia 0. Na przykład,

  • 0,000124 staje się 0,124 × 10-3
  • 237,141 staje się 0,237141 × 10 3

Oznacza to, że mantysa zawsze będzie w formie

0.α 1 α 2 ... α t x β str

gdzie β jest podstawą reprezentacji. Ale ponieważ ułamek jest liczbą binarną, α 1 będzie zawsze równy 1, więc ułamek można przepisać na 1.α 2 α 3 ... α t + 1 × 2 p, a początkowe 1 można założyć implicite, robiąc miejsce na dodatkowy bit (α t + 1 ).

Oczywiście prawdą jest, że podwójna liczba 32 to 64, ale nie od tego pochodzi to słowo.

Precyzja określa liczbę cyfr dziesiętnych, które są poprawne , czyli bez jakiegokolwiek błędu reprezentacji lub zbliżenia. Innymi słowy, wskazuje, ile cyfr dziesiętnych można bezpiecznie użyć.

Mając to na uwadze, łatwo oszacować liczbę cyfr dziesiętnych, których można bezpiecznie użyć:

  • pojedyncza precyzja : log 10 (2 24 ), czyli około 7 ~ 8 cyfr dziesiętnych
  • podwójna precyzja : log 10 (2 53 ), czyli około 15 ~ 16 cyfr dziesiętnych
Alessandro
źródło
19

OK, podstawowa różnica w maszynie polega na tym, że podwójna precyzja wykorzystuje dwa razy więcej bitów niż pojedynczy. W zwykłej implementacji jest to 32 bity dla pojedynczego, 64 bity dla podwójnego.

Ale co to znaczy ? Jeśli przyjmiemy standard IEEE, wtedy pojedyncza liczba precyzyjna ma około 23 bity mantysy i maksymalny wykładnik około 38; podwójna precyzja ma 52 bity mantysy i maksymalny wykładnik około 308.

Szczegóły jak zwykle na Wikipedii .

Charlie Martin
źródło
11

Aby dodać do wszystkich wspaniałych odpowiedzi tutaj

Przede wszystkim float i double służą do reprezentacji liczb ułamkowych. Tak więc różnica między tymi dwoma wynika z faktu, z jaką precyzją mogą przechowywać liczby.

Na przykład: Muszę przechowywać 123.456789 Jeden może być w stanie przechowywać tylko 123.4567, podczas gdy inny może być w stanie zapisać dokładny 123.456789.

Zasadniczo chcemy wiedzieć, jak dokładnie można zapisać liczbę i nazywamy to precyzją.

Cytując @Alessandro tutaj

Precyzja wskazuje liczbę cyfr dziesiętnych, które są poprawne , tj. Bez jakiegokolwiek błędu reprezentacji lub aproksymacji. Innymi słowy, wskazuje, ile cyfr dziesiętnych można bezpiecznie użyć.

Float może dokładnie przechowywać około 7-8 cyfr w części ułamkowej, podczas gdy Double może dokładnie przechowywać około 15-16 cyfr w części ułamkowej

Tak więc liczba zmiennoprzecinkowa może przechowywać podwójną ilość części ułamkowej. Dlatego Double nazywa się double the float

Prosty chłopak
źródło
7

Jeśli chodzi o pytanie: „Czy ps3 i xbxo 360 mogą wykonywać operacje zmiennoprzecinkowe podwójnej precyzji, czy tylko pojedynczą precyzję, a ogólnie rzecz biorąc, czy możliwości podwójnej precyzji są wykorzystywane (jeśli istnieją?)”.

Uważam, że obie platformy nie są zdolne do podwójnego zmiennoprzecinkowego. Oryginalny procesor Cell miał tylko 32-bitowe zmiennoprzecinkowe, tak samo jak sprzęt ATI, na którym oparty jest XBox 360 (R600). Komórka otrzymała później obsługę podwójnej liczby zmiennoprzecinkowej, ale jestem prawie pewien, że PS3 nie korzysta z tego wiórów.

codekaizen
źródło
5

Zasadniczo arytmetyka zmiennoprzecinkowa pojedynczej precyzji zajmuje się 32-bitowymi liczbami zmiennoprzecinkowymi, podczas gdy podwójna precyzja zajmuje się 64 bitami.

Liczba bitów w podwójnej precyzji zwiększa maksymalną wartość, która może być przechowywana, jak również zwiększa precyzję (tj. Liczbę cyfr znaczących).

cletus
źródło
5

Wszystkie wyjaśniono szczegółowo i nic nie mógłbym dodać. Chociaż chciałbym to wyjaśnić w kategoriach Layman's lub prostym ANGIELSKIM

1.9 is less precise than 1.99
1.99 is less precise than 1.999
1.999 is less precise than 1.9999

.....

Zmienna, która może przechowywać lub reprezentować wartość „1,9”, zapewnia mniejszą dokładność niż zmienna, która może przechowywać lub reprezentować 1,9999. Te ułamki mogą stanowić ogromną różnicę w dużych obliczeniach.

Asad
źródło
2

Podwójna precyzja oznacza, że ​​przechowywanie liczb zajmuje dwa razy więcej czasu niż słowo. W 32-bitowym procesorze wszystkie słowa są 32-bitowe, więc liczby podwójne są 64-bitowe. W odniesieniu do wydajności oznacza to, że wykonywanie operacji na liczbach o podwójnej precyzji zajmuje trochę więcej czasu. Masz więc lepszy zasięg, ale jest mały spadek wydajności. To trafienie jest nieco łagodzone przez sprzętowe jednostki zmiennoprzecinkowe, ale nadal tam jest.

N64 wykorzystywał NEC VR4300 oparty na MIPS R4300i, który jest 64-bitowym procesorem, ale procesor komunikuje się z resztą systemu za pośrednictwem 32-bitowej magistrali. Tak więc większość programistów używała liczb 32-bitowych, ponieważ są one szybsze, a większość gier w tamtym czasie nie wymagała dodatkowej precyzji (więc używali liczb zmiennoprzecinkowych, a nie podwójnych).

Wszystkie trzy systemy mogą wykonywać operacje pływające o pojedynczej i podwójnej precyzji, ale może to nie być spowodowane wydajnością. (chociaż prawie wszystko po n64 używało 32-bitowej magistrali, więc ...)

Alex
źródło
1

Przede wszystkim float i double służą do reprezentacji liczb ułamkowych. Tak więc różnica między tymi dwoma wynika z faktu, z jaką precyzją mogą przechowywać liczby.

Na przykład: Muszę przechowywać 123.456789 Jeden może być w stanie przechowywać tylko 123.4567, podczas gdy inny może być w stanie zapisać dokładny 123.456789.

Zasadniczo chcemy wiedzieć, jak dokładnie można zapisać liczbę i nazywamy to precyzją.

Cytując @Alessandro tutaj

Precyzja wskazuje liczbę poprawnych cyfr dziesiętnych, tj. Bez jakiegokolwiek błędu w reprezentacji lub aproksymacji. Innymi słowy, wskazuje, ile cyfr dziesiętnych można bezpiecznie użyć.

Float może dokładnie przechowywać około 7-8 cyfr w części ułamkowej, podczas gdy Double może dokładnie przechowywać około 15-16 cyfr w części ułamkowej

Tak więc double może przechowywać podwojoną ilość części ułamkowej jak float. Dlatego Double nazywa się double the float

djb7861
źródło
0

Zgodnie z IEEE754 • Standard dla przechowywania zmiennoprzecinkowego • Standardy 32 i 64-bitowe (pojedyncza precyzja i podwójna precyzja) • Odpowiednio wykładnik 8 i 11 bitowy • Rozszerzone formaty (mantysa i wykładnik) dla wyników pośrednich

Abdullah Al Mamun
źródło
-3

Liczba pojedynczej precyzji wykorzystuje 32 bity, gdzie MSB jest bitem znaku, podczas gdy liczba podwójnej precyzji używa 64 bitów, MSB jest bitem znaku

Pojedyncza precyzja

SEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)

Podwójna precyzja:

SEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)

Steve Bennett
źródło