Kropka dziesiętna nie jest nigdzie wyraźnie zapisywana; to problem z wyświetlaniem.
Poniższe wyjaśnienie stanowi uproszczenie; Pomijam wiele ważnych szczegółów, a moje przykłady nie mają reprezentować żadnej rzeczywistej platformy. Powinno to dać ci wyobrażenie o tym, jak wartości zmiennoprzecinkowe są reprezentowane w pamięci i związanych z nimi problemach, ale będziesz chciał znaleźć bardziej wiarygodne źródła, takie jak Co każdy informatyk powinien wiedzieć o arytmetyce zmiennoprzecinkowej .
Zacznij od przedstawienia wartości zmiennoprzecinkowej w wariancie notacji naukowej, używając podstawy 2 zamiast podstawy 10. Na przykład wartość 3.14159 można przedstawić jako
0,7853975 * 2 2
0.7853975 to znaczenie , czyli mantysa; jest to część liczby zawierająca cyfry znaczące. Wartość tę mnoży się przez podstawę 2 podniesioną do potęgi 2, aby uzyskać 3,14159.
Liczby zmiennoprzecinkowe są kodowane przez przechowywanie znaczenia i wykładnika (wraz z bitem znaku).
Typowy układ 32-bitowy wygląda mniej więcej tak:
3 32222222 22211111111110000000000
1 09876543 21098765432109876543210
+-+--------+-----------------------+
| | | |
+-+--------+-----------------------+
^ ^ ^
| | |
| | +-- significand
| |
| +------------------- exponent
|
+------------------------ sign bit
Podobnie jak podpisane typy liczb całkowitych, bit najwyższego rzędu wskazuje znak; 0 oznacza wartość dodatnią, 1 oznacza ujemną.
Kolejnych 8 bitów jest używanych dla wykładnika. Wykładniki mogą być dodatnie lub ujemne, ale zamiast rezerwować kolejny bit znaku, są one kodowane w taki sposób, że 10000000 reprezentuje 0, więc 00000000 reprezentuje -128, a 11111111 reprezentuje 127.
Pozostałe bity są używane dla znaczenia. Każdy bit reprezentuje ujemną moc 2 licząc od lewej, więc:
01101 * 2 = 0 -1 + 1 * 2 -2 + 1 * 2 -3 + 0 * 2 -4 + 1 * 2 -5
= 0,25 + 0,125 + 0,03125
= 0,40625
Niektóre platformy zakładają „ukryty” bit wiodący w znaczeniu, który jest zawsze ustawiony na 1, więc wartości w znaczeniu są zawsze między [0,5, 1). Pozwala to tym platformom przechowywać wartości z nieco większą precyzją (więcej na ten temat poniżej). Mój przykład tego nie robi.
Nasza wartość 3,14159 byłaby reprezentowana jako coś w rodzaju
0 10000010 11001001000011111100111
^ ^ ^
| | |
| | + --- znaczenie = 0,7853975 ...
| |
| + ------------------- wykładnik = 2 (130-128)
|
+ ------------------------- znak = 0 (dodatni)
wartość = -1 (znak) * 2 (wykładnik) * (znaczenie)
wartość = -1 0 * 2 2 * 0,7853975 ...
wartość = 3,14159 ...
Coś, co zauważysz, jeśli dodasz wszystkie bity w znaczeniu, to to, że nie sumują się one 0,7853975; faktycznie wychodzą na 0.78539747. Nie ma dość bitów, aby dokładnie zapisać wartość ; możemy przechowywać tylko przybliżenie. Liczba bitów w znaczeniu określa precyzję lub liczbę cyfr znaczących, które można zapisać. 23 bity dają nam około 6 cyfr dziesiętnych precyzji. 64-bitowe typy zmiennoprzecinkowe oferują wystarczającą liczbę bitów i dają około 12 do 15 cyfr precyzji. Należy jednak pamiętać, że istnieją wartości, których nie można dokładnie przedstawić bez względu na sposóbwiele używanych bitów. Podobnie jak wartości takie jak 1/3 nie mogą być reprezentowane przez skończoną liczbę cyfr dziesiętnych, podobnie jak wartości 1/10 nie mogą być reprezentowane przez skończoną liczbę bitów. Ponieważ wartości są przybliżone, obliczenia z nimi również są przybliżone, a błędy zaokrąglania kumulują się.
Liczba bitów w wykładniku określa zakres (minimalne i maksymalne wartości, które możesz reprezentować). Jednak w miarę zbliżania się do wartości minimalnych i maksymalnych zwiększa się różnica między wartościami reprezentatywnymi. Oznacza to, że jeśli nie możesz dokładnie przedstawić wartości między 0,785397 a 0,785398, to nie możesz dokładnie przedstawić wartości między 7,85397 a 7,85398 albo wartości między 78,5397 a 78,5398 lub wartości między 785397.0 a 785398.0. Zachowaj ostrożność, mnożąc bardzo duże (pod względem wielkości) liczby przez bardzo małe liczby.