2012-08-25 10 views
18

Dużo czytałem na temat pływaków, ale wszystko to jest niepotrzebnie zaangażowane. myślę Mam go dość dużo rozumieć, ale jest tylko jedna rzecz, chciałbym wiedzieć na pewno:Jakie typy liczb można przedstawić w binarnym zmiennoprzecinkowaniu?

wiem, że frakcje postaci 1/pow(2,n), z n liczbą całkowitą, może być dokładnie reprezentowana w liczbach zmiennoprzecinkowych. Oznacza to, że jeśli dodaję do siebie 3200 razy 1/32, otrzymam dokładnie 1,000,000.

Co z czymś takim jak 1/(32+16)? To jedna z sumy dwóch mocy dwóch, czy to działa? Czy to jest 1/32+1/16, które działa? W tym miejscu jestem zdezorientowany, więc jeśli ktokolwiek mógłby to wyjaśnić, byłbym wdzięczny.

Odpowiedz

27

Zasadę można podsumować następująco:

  • Szereg mogą być reprezentowane dokładnie w binarnym, jeśli czynniki pierwsze mianowniku zawiera tylko 2. (czyli mianownik jest potęgą dwójki)

Tak więc 1/(32 + 16) nie można przedstawić w systemie binarnym, ponieważ ma on współczynnik 3 w mianowniku. Ale jest 1/32 + 1/16 = 3/32.

To powiedziawszy, istnieje więcej ograniczeń, które można przedstawić w typie zmiennoprzecinkowym. Na przykład, masz tylko 53 bity mantysy w IEEE double, więc 1/2 + 1/2^500 nie jest reprezentowalny.

Możesz więc zrobić sumę mocy dwóch, o ile zakres wykładników nie przekracza 53 mocy.


Uogólniając to inne zasady:

  • Numer może być dokładnie przedstawiony na podstawie 10, gdy czynniki pierwsze mianowniku składa się z tylko 2 oraz 5 jest.

  • liczbą wymierną X można dokładnie reprezentowane w bazie N jeśli czynniki pierwsze mianowniku X zawiera tylko liczby pierwsze znalezione w faktoryzacji N.

+3

Więc jeśli mam to prawo, mogę użyć dowolnej liczby "X/Y", o ile "Y" jest potęgą 2, a "X" jest liczbą mniejszą niż "2^53"? –

+2

Tak, zgadza się. (z wyłączeniem przypadków przekroczenia/niedomiaru) – Mysticial

+0

@Mysticial: +1 dla odpowiedzi, ale mam wątpliwości. 24/48 = 0,5, jednak zgodnie z powyższą zasadą, nie powinno być możliwe do reprezentacji, ponieważ 3 jest jednym z głównych czynników 48, który nie jest jednym z głównych czynników 10. Czemu? – legends2k

4

numery zmiennoprzecinkowe dosłownie reprezentowane przy użyciu postać:

1.m * 2^e 

przypadku 1.m jest ułamkiem binarnych i e jest dodatnia lub ujemna.

Jako takie, można reprezentować 1/32 + 1/16 dokładnie, jak: (. 1.10 jest binarny ułamek równowartość 1,5)

1.1000000 * 2^-4 

1/48 jednak nie jest odwzorowane w tym formacie.

+0

(Myślę, że masz na myśli '1.m * 2^e'.) – huon

+0

Derp. Tak oczywiście. :) – duskwuff

+0

Czy to nie powinno być "1.1000000 * 2^-4"? – mkeiser

0

Jeszcze nie wspomniano, że semantycznie liczba zmiennoprzecinkowa może być najlepiej traktowana jako reprezentująca zakres wartości.Zakres wartości ma bardzo precyzyjnie zdefiniowany punkt środkowy, a specyfikacja IEEE na ogół wymaga, aby wynikiem obliczeń zmiennoprzecinkowych była liczba, której zakres zawiera punkt, który można uzyskać operując na punktach środkowych pierwotnych liczb, ale w kolejności:

 
    double N1 = 0.1; 
    float N2 = (float)N1; 
    double N3 = N2; 

N2 jest jednoznaczne poprawne pojedynczej precyzji reprezentacja wartości, które były reprezentowane w N1, mimo głupie wymogu języku, aby wykorzystać wyraźny odcień. N3 będzie reprezentować jedną z wartości, które może reprezentować N2 (specyfikacja języka wybiera wartość double, której zakres jest wyśrodkowany w środku zakresu float). Zauważ, że podczas gdy N2 reprezentuje wartość swojego typu, którego zakres zawiera poprawną wartość, N3 tego nie robi.

Nawiasem mówiąc, konwersja liczby z ciągu na float w językach .net i .net zdaje się przechodzić pośrednią konwersję na double, która może czasami zmieniać wartość. Na przykład, mimo że wartość 13571357 jest reprezentowana jako float pojedynczej precyzji, wartość 13571357.499999999069f zostanie zaokrąglona do 13571358 (mimo że jest to oczywiście bliższe 13571357).

+0

1. "głupie wymowy języka do korzystania z wyraźnej obsady": W jakim języku mówisz? C nie wymaga tutaj obsady ... – glglgl

+0

@glglgl: Cytowany przykład kodu byłby poprawny w C, Java lub C#; dwa ostatnie języki wymagają odlewu do 'float', ale nie do" double ". – supercat

+0

Ok, dzięki. Komentarz 2. już się nie stosuje, pomyślałem o łańcuchu -> double -> float conversion i wygląda na to, że właśnie tu jesteś. – glglgl

8

skończoną liczbę można przedstawić na wspólnym IEEE 754 podwójnej precyzji formacie, wtedy i tylko wtedy, gdy jest równa m • 2 e niektórych liczb M i E, takie, które -2 < M i -1074 ≤ e ≤ 971.

do jednorazowego precyzją -2 < M i -149 ≤ e ≤ 104.

W przypadku podwójnej precyzji są to konsekwencje faktów, w których format podwójnej precyzji używa 52 bitów do przechowywania znacznika (który zwykle ma 53 bity z powodu niejawnego 1) i wykorzystuje 11 bitów do przechowywania wykładnika. 11 bitów koduje liczby od 0 do 2047, ale 0 i 2047 są wyłączone do celów specjalnych, a zakodowana liczba jest stronnicza przez 1023, więc reprezentuje nieobciążone wykładniki od -1022 do 1023. Jednak te bezstronne wykładniki są znaczące w przedziale [1, 2), a te znaczące mają ułamki. Wyrazić mantysy jako liczba całkowita I dostosowane zakres wykładnik przez 52. Pojedyncze precyzji jest podobna, z 23 bitów do przechowywania mantysy 24-bitowy, 8 bitów na wykładnik i odchyleń w 127

wyrażających reprezentowalne liczby wykorzystujące liczbę całkowitą pomnożoną przez potęgę dwóch zamiast bardziej pospolitych znaczeń cząstkowych upraszczają teorię liczb i inne rozumowanie właściwości zmiennoprzecinkowych. Użyłem go w tej odpowiedzi, ponieważ pozwala on na zwięzłe przedstawienie zestawu reprezentowalnych wartości.

+0

Zobacz, że jest to rodzaj "zbyt głęboko zaangażowanego", o którym wspomniałem w swoim pytaniu ... –

+2

@Kolink: Odpowiedź sama w sobie jest pojedynczym zdaniem, które dokładnie określa, które liczby mogą i nie mogą być reprezentowane, używając tylko znanych pojęć z liczb całkowitych , mnożenie, moce i mniej niż (lub równe). O ile prostsze, niż możesz dostać? Masz liczbę całkowitą razy moc dwóch, a liczba całkowita i moc muszą być w pewnych granicach. Reszta odpowiedzi to tylko wyjaśnienie, skąd pochodzi zdanie. –

+1

+1. Edytowane, aby naprawić górne granice dla e. –

Powiązane problemy