Dla jasności, jeśli używam języka, który implementuje zmiennoprzecinkowe IEE 754 i oświadczam:
float f0 = 0.f;
float f1 = 1.f;
... a następnie wydrukuj je z powrotem, otrzymam 0,0000 i 1,0000 - dokładnie.
Ale IEEE 754 nie jest w stanie przedstawić wszystkich liczb wzdłuż rzeczywistej linii. Bliskie zeru „luki” są małe; w miarę oddalania się odstępy się powiększają.
Więc moje pytanie brzmi: dla float IEEE 754, która jest pierwszą (najbliższą zeru) liczbą całkowitą, której nie można dokładnie przedstawić? Na razie jestem naprawdę zainteresowany tylko 32-bitowymi floatami, chociaż będę zainteresowany usłyszeniem odpowiedzi na 64-bitowe, jeśli ktoś ją poda!
Pomyślałem, że będzie to tak proste, jak obliczenie 2 bitów_mantissy i dodanie 1, gdzie bity_mantysy to liczba bitów ujawnionych przez standard. Zrobiłem to dla 32-bitowych pływaków na moim komputerze (MSVC ++, Win64) i wydawało się jednak w porządku.
źródło
Odpowiedzi:
2 bity mantysy + 1 + 1
+1 w wykładniku (bity mantysy + 1) wynika z faktu, że jeśli mantysa zawiera
abcdef...
liczbę, którą reprezentuje, to w rzeczywistości1.abcdef... × 2^e
zapewnia dodatkowy ukryty bit precyzji.Dlatego pierwszą liczbą całkowitą, której nie można dokładnie przedstawić i która zostanie zaokrąglona, jest:
For
float
, 16,777,217 (2 24 + 1).Dla
double
9,007,199,254,740,993 (2 53 + 1).źródło
float
i ustawiłem go na 16,777,217. Ale kiedy go wydrukowałem, przycout
jego użyciu otrzymałem 16 777 216. UżywamC++
. Dlaczego nie mogę dostać 16,777,217?(1 << std::numeric_limits<float>::digits) + 1
, aw C(1 << FLT_MANT_DIG) + 1
,. Pierwsza jest fajna, ponieważ może być częścią szablonu. Nie dodawaj +1, jeśli chcesz tylko największej reprezentowalnej liczby całkowitej.Największa wartość reprezentowana przez n- bitową liczbę całkowitą to 2 n -1. Jak wspomniano powyżej, a
float
ma 24 bity precyzji w znaczeniu, co wydaje się sugerować, że 2 24 nie będzie pasować.Jednak .
Potęgi 2 w zakresie wykładnika są dokładnie reprezentowane jako 1,0 × 2 n , więc 2 24 mogą pasować, a zatem pierwsza nieprzedstawialna liczba całkowita dla
float
to 2 24 +1. Jak wspomniano wyżej. Jeszcze raz.źródło