To nie jest duplikat pytania, gdy czytam poprzednie pytanie.
Czy ktoś może mi pomóc w zrozumieniu how float values are stored in the memory
.
Mam wątpliwości, czy tutaj wartości zmiennoprzecinkowe zawierają „ .'
( for example 3.45
) jak '.'
będą reprezentowane w pamięci?
Czy ktoś może mi wyjaśnić za pomocą diagramu?
c
memory
floating-point
użytkownik2720323
źródło
źródło
Odpowiedzi:
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 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:
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:
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
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.
źródło
W
.
ogóle nie jest przechowywany. Po pierwsze, powinieneś zrozumieć notację inżynierską, która ma współczynnik stałej precyzji i wykładnik liczb całkowitych:1
wynosi 1,0 · 10 0 =1.0E0
, 2 to2.0E0
, 10 to1.0E1
itd. Pozwala to na bardzo krótkie notowanie dużych liczb. Miliard to1.0E9
. Współczynnik zanimE
zwykle zapisaną w postaci liczby stałej precyzji:1.00000E9
. Wynika to z tego, że jeden miliard jeden i jeden = 1 000 000 001 i jeden miliard są takie same w tym zapisie, gdy precyzja nie jest wystarczająco duża. Pamiętaj również, że czynnik nigdy nie potrzebuje wiodącego zera. Zamiast tego wykładnik potęgi można zmniejszać, dopóki tak się nie stanie.W pamięci liczba zmiennoprzecinkowa jest reprezentowana podobnie: jeden bit ma znak, niektóre bity tworzą współczynnik jako liczba o stałej precyzji („mantysa”), pozostałe bity tworzą wykładnik wykładniczy. Istotne różnice w notacji inżynierskiej podstawy 10 polegają na tym, że wykładnik ma teraz podstawę 2. Dokładny rozmiar każdej części zależy od dokładnego standardu zmiennoprzecinkowego, którego używasz.
źródło
float
wynosi2^-22 * exponent
około 1/4194304.