JavaRush /Blog Java /Random-PL /Co kryje się w liczbie zmiennoprzecinkowej i jak to dział...
Ivan
Poziom 2
Харьков

Co kryje się w liczbie zmiennoprzecinkowej i jak to działa?

Opublikowano w grupie Random-PL

Treść:

Zdjęcie: http://pikabu.ru/

Wstęp

Już w pierwszych dniach nauki Javy natknąłem się na tak ciekawy rodzaj prymitywów jak liczby zmiennoprzecinkowe. Od razu zainteresowały mnie ich cechy, a jeszcze bardziej sposób, w jaki zostały zapisane w kodzie binarnym (który jest ze sobą połączony). W przeciwieństwie do dowolnego zakresu liczb całkowitych, nawet w bardzo małym zakresie (na przykład od 1 do 2) istnieje ich nieskończona liczba. A mając skończoną wielkość pamięci, nie da się wyrazić tego zestawu. Jak więc są wyrażone binarnie i jak działają? Niestety, wyjaśnienia na wiki i całkiem fajny artykuł na temat Habré tutaj nie dały mi pełnego zrozumienia, chociaż położyły podwaliny. Uświadomienie sobie tego przyszło dopiero po przeczytaniu tego artykułu analitycznego następnego ranka po jego przeczytaniu.

Wycieczka w historię

( zaczerpnięte z tego artykułu o Habré ) W latach 60-70, kiedy komputery były duże, a programy małe, nadal nie było jednego standardu obliczeń, a także standardu wyrażania samej liczby zmiennoprzecinkowej. Każdy komputer robił to inaczej i każdy miał swoje własne błędy. Jednak w połowie lat 70. Intel zdecydował się stworzyć nowe procesory z obsługiwaną „ulepszoną” arytmetyką i jednocześnie ją ujednolicić. Do jego opracowania sprowadzono profesorów Williama Kahana i Johna Palmera (nie, nie autora książek o piwie). Był pewien dramat, ale opracowano nowy standard. Teraz ten standard nazywa się IEEE754

Format liczb zmiennoprzecinkowych

Nawet w podręcznikach szkolnych każdy miał do czynienia z nietypowym sposobem zapisywania bardzo dużych lub bardzo małych liczb w postaci 1,2 × 10 3 lub 1,2 E3 , co równa się 1,2 × 1000 = 1200 . Nazywa się to metodą notacji wykładniczej. W tym przypadku mamy do czynienia z wyrażeniem liczby za pomocą wzoru: N=M×n p , gdzie
  • N = 1200 - liczba wynikowa
  • M = 1,2 - mantysa - część ułamkowa, bez uwzględnienia rzędów
  • n = 10 jest podstawą porządku. W tym przypadku i gdy nie mówimy o komputerach, podstawą jest liczba 10
  • p = 3 - stopień podstawy
Dość często przyjmuje się, że podstawą rzędu jest 10 i zapisuje się tylko mantysę i wartość podstawy, oddzielając je literą E. W naszym przykładzie podałem równoważne wpisy 1,2 × 10 3 i 1,2 E3 . Jeśli wszystko jest jasne i zakończyliśmy nostalgiczną wycieczkę do szkolnego programu nauczania, to teraz radzę o tym zapomnieć, ponieważ tworząc liczbę zmiennoprzecinkową mamy do czynienia z potęgi dwójki, a nie dziesiątek, tj. n = 2 , cała harmonijna formuła 1.2E3 rozpada się i naprawdę złamał mi mózg.

Znak i stopień

Co więc mamy? W rezultacie mamy również liczbę binarną, która składa się z mantysy – części, którą podniesiemy do potęgi i samej potęgi. Dodatkowo, podobnie jak w przypadku typów całkowitych, liczby zmiennoprzecinkowe posiadają bit określający znak – czy liczba będzie dodatnia, czy ujemna. Jako przykład proponuję rozważyć typ float, który składa się z 32 bitów. W przypadku liczb o podwójnej precyzji doublelogika jest taka sama, tylko jest dwa razy więcej bitów. Z 32 bitów pierwszy najbardziej znaczący jest przypisany do znaku, kolejne 8 bitów przydzielane jest do wykładnika - potęgi, do której podniesiemy mantysę, a pozostałe 23 bity - do mantysy. Aby to zademonstrować, spójrzmy na przykład: Co kryje się w liczbie zmiennoprzecinkowej i jak to działa - 1Pierwszy bit jest bardzo prosty. Jeśli wartość pierwszego bitu wynosi 0 , to otrzymana liczba będzie dodatnia . Jeśli bit ma wartość 1 , liczba będzie ujemna . Następny blok 8 bitów jest blokiem wykładniczym. Wykładnik zapisuje się jako zwykłą liczbę ośmiobitową i aby uzyskać wymagany stopień, od otrzymanej liczby należy odjąć 127. W naszym przypadku osiem bitów wykładnika to 10000001 . Odpowiada to liczbie 129 . Jeśli masz pytanie, jak to obliczyć, zdjęcie pokazuje szybką odpowiedź. Wersję rozszerzoną można uzyskać w dowolnym kursie algebry Boole'a. Co kryje się w liczbie zmiennoprzecinkowej i jak to działa - 21×2 7 + 0×2 6 + 0×2 5 + 0×2 4 + 0×2 3 + 0×2 2 + 0×2 1 + 1×2 0 = 1×128 + 1×1 = 128+ 1=129 Nietrudno obliczyć, że maksymalna liczba, jaką możemy uzyskać z tych 8 bitów to 11111111 2 = 255 10 (indeks dolny 2 i 10 oznaczają systemy liczb binarnych i dziesiętnych) Jeśli jednak użyjemy tylko dodatnich wartości wykładniczych ( od 0 do 255 ), to wynikowe liczby będą miały wiele liczb przed przecinkiem dziesiętnym, ale nie po? Aby uzyskać ujemne wartości stopnia, należy od wygenerowanego wykładnika odjąć 127 . Zatem zakres stopni będzie wynosić od -127 do 128 . Korzystając z naszego przykładu, wymagany stopień będzie wynosić 129-127 = 2 . Zapamiętajmy na razie tę liczbę.

Mantysa

Teraz o mantysie. Składa się z 23 bitów, ale na początku zawsze sugeruje się inną jednostkę, dla której bity nie są przydzielone. Odbywa się to ze względów praktycznych i ekonomicznych. Tę samą liczbę można wyrazić w różnych potęgach, dodając zera do mantysy przed lub po przecinku. Najłatwiej to zrozumieć, posługując się wykładnikiem dziesiętnym: 120 000 = 1,2×10 5 = 0,12×10 6 = 0,012×10 7 = 0,0012×10 8 itd. Natomiast wpisując stałą liczbę w nagłówku mantysy, za każdym razem otrzymamy nowe liczby. Przyjmijmy za pewnik, że przed naszymi 23 bitami będzie jeszcze jeden z jednym. Zwykle bit ten jest oddzielony od reszty kropką, co jednak nic nie znaczy. Tak jest po prostu wygodniej 1. 111000000000000000000000 Co kryje się w liczbie zmiennoprzecinkowej i jak to działa - 3Teraz wynikową mantysę należy podnieść do potęgi od lewej do prawej, zmniejszając moc o jeden z każdym krokiem. Zaczynamy od wartości potęgi, którą otrzymaliśmy w wyniku obliczeń, czyli 2 (celowo wybrałem prosty przykład, aby nie wpisywać każdej wartości potęgi dwójki i nie obliczałem ich w tabeli powyżej, gdy odpowiedni bit to zero) Co kryje się w liczbie zmiennoprzecinkowej i jak to działa - 41×2 2 + 1×2 1 + 1×2 0 + 1×2 -1 = 1×4 + 1×2 + 1×1 + 1×0,5 = 4+2+1+0,5 = 7.5 i otrzymałem wynik 7.5 , poprawność można sprawdzić np. pod tym linkiem

Wyniki

Standardowa liczba zmiennoprzecinkowa floatskłada się z 32 bitów, pierwszy bit to znak (+ lub -), kolejnych osiem to wykładnik, kolejnych 23 to mantysa. Znak By - jeśli bit 0 jest liczbą dodatnią. Jeśli bit 1 jest ujemny. Wykładniczo – zamieniamy bitowo na liczbę dziesiętną (pierwszy bit od lewej to 128 , drugi to 64 , trzeci to 32 , czwarty to 16 , piąty to 8 , szósty to 4 , siódmy to 2 , ósma to 1 ), od uzyskanej liczby odejmij 127 , otrzymamy stopień, od którego zaczniemy. Zgodnie z mantysą - do istniejących 23 bitów z przodu dodajemy kolejny bit o wartości 1 i od niego zaczynamy podnosić do otrzymanej mocy, zmniejszając tę ​​moc z każdym kolejnym bitem. To wszystko, ludzie, dzieci! Co kryje się w liczbie zmiennoprzecinkowej i jak to działa - 5PS: W ramach pracy domowej, korzystając z tego artykułu, zostaw w komentarzach swoją wersję tego, dlaczego pojawiają się błędy precyzji w przypadku dużej liczby operacji arytmetycznych na liczbach zmiennoprzecinkowych
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION