Was ist die größte "nicht schwebende" Ganzzahl, die in einem IEEE 754-Doppeltyp gespeichert werden kann, ohne an Genauigkeit zu verlieren?
quelle
Was ist die größte "nicht schwebende" Ganzzahl, die in einem IEEE 754-Doppeltyp gespeichert werden kann, ohne an Genauigkeit zu verlieren?
Die größte / größte Ganzzahl, die in einem Double gespeichert werden kann, ohne an Genauigkeit zu verlieren, entspricht dem größtmöglichen Wert eines Double. Das heißt, DBL_MAX
oder ungefähr 1,8 × 10 308 (wenn Ihr Double ein IEEE 754 64-Bit-Double ist). Es ist eine ganze Zahl. Es ist genau dargestellt. Was willst du noch?
Fragen Sie mich weiter, was die größte Ganzzahl ist, damit sie und alle kleineren Ganzzahlen in IEEE 64-Bit-Doubles gespeichert werden können, ohne an Genauigkeit zu verlieren. Ein IEEE 64-Bit-Double hat 52 Mantisse-Bits, also denke ich, dass es 2 53 ist :
Oder eine andere Sichtweise: Sobald die Vorspannung vom Exponenten entfernt wurde und das Vorzeichenbit als für die Frage irrelevant ignoriert wurde, ist der von einem Double gespeicherte Wert eine Potenz von 2 plus eine 52-Bit-Ganzzahl multipliziert mit 2 Exponent - 52 . Mit Exponent 52 können Sie also alle Werte von 2 52 bis 2 53 - 1 speichern. Mit Exponent 53 ist die nächste Zahl, die Sie nach 2 53 speichern können, 2 53 + 1 × 2 53 - 52 . Ein Präzisionsverlust tritt also zuerst bei 2 53 + 1 auf.
9007199254740992 (das sind 9.007.199.254.740.992) ohne Garantie :)
Programm
Ergebnis
quelle
double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);
der das gleiche Ergebnis liefertwhile (dbl == --dbl)
wird für immer oder gar nicht schleifen. :) (in diesem Fall überhaupt nicht, da es sich um eine 2 ^ N handelt). Sie müssen es von unten nähern. Es wird in der Tat auch zu einem Ergebnis führen, das unter dem erwarteten Ergebnis liegt (da das Einchecken in der while-Schleife dbl dekrementiert). Und es hängt von der Reihenfolge der Ausführung ab, ob die Dekrementierung vor oder nach der Auswertung der linken Seite erfolgt (was meines Wissens undefiniert ist). Wenn es das erstere ist, wird es immer wahr sein und für immer eine Schleife bilden.while (dbl + 1 != dbl) dbl++;
, dassdbl + 1 != dbl
bewerten kann mitlong double
Mathematik - prüfenFLT_EVAL_METHOD == 2
. Dies könnte in einer Endlosschleife enden.Wikipedia hat dies im gleichen Zusammenhang mit einem Link zu IEEE 754 zu sagen :
2 ^ 53 ist etwas mehr als 9 * 10 ^ 15.
quelle
Die größte Ganzzahl, die in IEEE 754 double (64-Bit) dargestellt werden kann, entspricht dem größten Wert, den der Typ darstellen kann, da dieser Wert selbst eine Ganzzahl ist.
Dies wird dargestellt als
0x7FEFFFFFFFFFFFFF
, das sich zusammensetzt aus:0x7FE
(2046, der 1023 darstellt, nachdem die Vorspannung subtrahiert wurde) anstelle von0x7FF
(2047, der aNaN
oder unendlich anzeigt ).0xFFFFFFFFFFFFF
die 52 Bit alle 1 ist.Im Binärbereich ist der Wert die implizite 1, gefolgt von weiteren 52 Einsen von der Mantisse und 971 Nullen (1023 - 52 = 971) vom Exponenten.
Der genaue Dezimalwert ist:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
Dies ist ungefähr 1,8 x 10 308 .
quelle
Sie müssen sich die Größe der Mantisse ansehen. Eine IEEE 754 64-Bit-Gleitkommazahl (mit 52 Bit plus 1 impliziten) kann genau ganze Zahlen mit einem Absolutwert von weniger als oder gleich 2 ^ 53 darstellen.
quelle
1,7976931348623157 × 10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
quelle
DECIMAL_DIG
from<float.h>
sollte zumindest eine vernünftige Annäherung daran geben. Da die sich mit Dezimalstellen, und es ist wirklich binär gespeichert ist, können Sie wahrscheinlich speichern etwas ein wenig größer , ohne Präzision zu verlieren, aber genau , wie viel ist schwer zu sagen. Ich nehme an, Sie sollten es ausFLT_RADIX
und herausfinden könnenDBL_MANT_DIG
, aber ich bin mir nicht sicher, ob ich dem Ergebnis vollständig vertrauen würde.quelle
double
direkt einem bestimmten IEEE-Typ entspricht, aber das ist nicht erforderlich, und als diese Antwort geschrieben wurde, erwähnte die Frage auch keinen bestimmten IEEE-Typ.