Welches ist die erste Ganzzahl, die ein IEEE 754-Float nicht genau darstellen kann?

161

Wenn ich aus Gründen der Klarheit eine Sprache verwende, die IEE 754-Floats implementiert, erkläre ich:

float f0 = 0.f;
float f1 = 1.f;

... und dann wieder ausdrucken, bekomme ich 0,0000 und 1,0000 - genau.

IEEE 754 ist jedoch nicht in der Lage, alle Zahlen entlang der realen Linie darzustellen. Nahe Null sind die "Lücken" klein; Je weiter Sie entfernt sind, desto größer werden die Lücken.

Meine Frage lautet also: Für einen IEEE 754-Float, welche ist die erste Ganzzahl (am nächsten bei Null), die nicht genau dargestellt werden kann? Ich bin im Moment nur wirklich mit 32-Bit-Floats beschäftigt, obwohl ich interessiert sein würde, die Antwort für 64-Bit zu hören, wenn jemand sie gibt!

Ich dachte, dies wäre so einfach wie das Berechnen von 2 Bits von Mantissa und das Hinzufügen von 1, wobei Bits von Mantissa die Anzahl der Bits sind, die der Standard verfügbar macht. Ich habe dies für 32-Bit-Floats auf meinem Computer (MSVC ++, Win64) getan, und es schien jedoch in Ordnung zu sein.

Floomi
quelle
Warum haben Sie eine hinzugefügt, wenn Sie eine nicht darstellbare Nummer wollten? Und welche Nummer haben Sie benutzt oder bekommen? Und sind das Hausaufgaben? Und Ihr Fragentitel sagt "Ganzzahl", aber Ihre Frage sagt "float".
Msw
5
Weil ich dachte, dass das Maximieren der Mantisse mir die höchste darstellbare Zahl geben würde. 2 ^ 22. Nein, das ist eine Frage der Neugier. Ich habe mich immer schuldig gefühlt, Ints in Floats zu setzen, auch wenn ich weiß, dass der fragliche Int immer sehr klein sein wird. Ich möchte wissen, wie hoch die Obergrenze ist. Soweit ich das beurteilen kann, sind Titel und Frage gleich, nur unterschiedlich formuliert.
Floomi
1
Duplikat von stackoverflow.com/questions/1848700/… ?
FrankH.
1
@KyleStrand zurückgesetzt ^ 2. Ich weiß nicht, warum mir damals einer korrekter erschien als der andere. Jetzt scheinen beide unangenehm im Vergleich zu "... ist die Anzahl der Bits ..."
Pascal Cuoq

Antworten:

211

2 Mantissenbits + 1 + 1

Die +1 im Exponenten (Mantissenbits + 1) ist, weil, wenn die Mantisse abcdef...die Zahl enthält, die sie darstellt, tatsächlich ist1.abcdef... × 2^e , ein zusätzliches implizites Bit an Genauigkeit bereitgestellt wird.

Daher ist die erste Ganzzahl, die nicht genau dargestellt werden kann und gerundet wird, folgende:
Für float16.777.217 (2 24 + 1).
Für double9.007.199.254.740.993 (2 53 + 1).

>>> 9007199254740993.0
9007199254740992
kennytm
quelle
Ich habe a deklariert floatund auf 16.777.217 gesetzt. Aber als ich es damit druckte, coutergab sich 16.777.216. Ich benutze C++. Warum kann ich nicht 16.777.217 bekommen?
Natriumnitrat
18
@ Natriumnitrat Überprüfen Sie den Titel der Frage. 16777217 ist die erste Ganzzahl, die nicht genau dargestellt werden kann.
Kennytm
OK danke. Ich war verwirrt, tut mir leid. Ich habe jedoch eine andere Frage: Sollte nach 16777216 nicht die nächste darstellbare Ganzzahl 2 * 16777216 sein? Wenn ich ein ähnliches Programm ausführe, erhalte ich 16777218 durch Hinzufügen von 2 zu 16777126.
Natriumnitrat
5
Die nächste Ganzzahl ist in der Tat 16777218, da 2 jetzt die letzte signifikante Binärziffer wird.
Kennytm
6
In C ++ ist das (1 << std::numeric_limits<float>::digits) + 1und in C , (1 << FLT_MANT_DIG) + 1. Ersteres ist schön, weil es Teil einer Vorlage sein kann. Fügen Sie nicht +1 hinzu, wenn Sie nur die größte darstellbare Ganzzahl möchten.
Henry Schreiner
38

Der größte Wert, der durch eine n- Bit-Ganzzahl dargestellt werden kann, ist 2 n -1. Wie oben erwähnt, hat a eine floatGenauigkeit von 24 Bit im Signifikanten, was zu bedeuten scheint, dass 2 24 nicht passen würden.

Allerdings .

Potenzen von 2 innerhalb des Bereichs des Exponenten sind genau als 1,0 × 2 n darstellbar , so dass 2 24 passen kann und folglich die erste nicht darstellbare ganze Zahl für float2 24 + 1 ist. Wie oben beschrieben. Nochmal.

also sprach ak
quelle
1
Dies erklärte deutlich den "extra impliziten Teil der Präzision" des anderen. Vielen Dank.
Chappjc