Java double
s sind im IEEE-754- Format, daher haben sie einen 52-Bit-Bruch; zwischen zwei benachbarten Zweierpotenzen (einschließlich einer und ausschließlich der nächsten) gibt es daher zwei bis 52 double
Potenzen , die sich unterscheiden (dh 4503599627370496 von ihnen). Das ist zum Beispiel die Anzahl der unterschiedlichen double
s zwischen 0,5 eingeschlossen und 1,0 ausgeschlossen, und genau so viele liegen auch zwischen 1,0 eingeschlossen und 2,0 ausgeschlossen und so weiter.
Das Zählen doubles
zwischen 0,0 und 1,0 ist schwieriger als zwischen Zweierpotenzen, da in diesem Bereich viele Zweierpotenzen enthalten sind und man sich auch mit den heiklen Fragen denormalisierter Zahlen befasst. 10 der 11 Bits der Exponenten decken den fraglichen Bereich ab. Wenn Sie also denormalisierte Zahlen (und ich denke ein paar Arten von Zahlen) einschließen, hätten NaN
Sie das 1024-fache des double
s zwischen Zweierpotenzen - 2**62
ohnehin nicht mehr als insgesamt . Ohne denormalisierte & c glaube ich, dass die Zählung 1023 mal sein würde 2**52
.
Für einen beliebigen Bereich wie "100 bis 100.1" ist es noch schwieriger, da die Obergrenze nicht genau als a dargestellt werden kann double
(kein exaktes Vielfaches einer Zweierpotenz). In praktischer Näherung könnte man sagen, dass der Bereich zwischen den Potenzen von zwei linear ist, da der Verlauf zwischen den Zweierpotenzen linear ist 0.1 / 64
(64 und 128)
(0.1 / 64) * 2**52
verschiedene double
s - was dazu kommt 7036874417766.4004
... ein oder zwei zu geben oder zu nehmen ;-).
2**64
mögliche Doppelwerte geben (da es sich um einen 64-Bit-Typ handelt), und anscheinend liegt ein RIESIGER Anteil dieser Werte dazwischen0..1
?Jeder
double
Wert, dessen Darstellung zwischen0x0000000000000000
und0x3ff0000000000000
im Intervall [0.0, 1.0] liegt. Das sind (2 ^ 62 - 2 ^ 52) unterschiedliche Werte (plus oder minus ein Paar, je nachdem, ob Sie die Endpunkte zählen).Das Intervall [1.0, 2.0] entspricht Darstellungen zwischen
0x3ff0000000000000
und0x400000000000000
; das sind 2 ^ 52 verschiedene Werte.Das Intervall [100.0, 101.0] entspricht Darstellungen zwischen
0x4059000000000000
und0x4059400000000000
; das sind 2 ^ 46 verschiedene Werte.Es gibt keine Doppel zwischen 10 ^ 100 und 10 ^ 100 + 1 . Keine dieser Zahlen ist mit doppelter Genauigkeit darstellbar, und es gibt keine Doppelzahlen, die zwischen ihnen liegen. Die nächsten zwei Zahlen mit doppelter Genauigkeit sind:
und
quelle
Andere haben bereits erklärt, dass es im Bereich [0.0, 1.0] etwa 2 ^ 62 Doppel gibt.
(Nicht wirklich überraschend: Es gibt fast 2 ^ 64 verschiedene endliche verdoppelt, von denen, sind die Hälfte positiv, und etwa die Hälfte diejenigen sind <1,0) .
Sie erwähnen jedoch Zufallszahlengeneratoren: Beachten Sie, dass ein Zufallszahlengenerator, der Zahlen zwischen 0,0 und 1,0 generiert, im Allgemeinen nicht alle diese Zahlen erzeugen kann . Normalerweise werden nur Zahlen der Form n / 2 ^ 53 mit n einer Ganzzahl erzeugt (siehe z. B. die Java-Dokumentation für nextDouble ). Daher gibt es normalerweise nur etwa 2 ^ 53 (+/- 1, abhängig davon, welche Endpunkte enthalten sind) mögliche Werte für die
random()
Ausgabe. Dies bedeutet, dass die meisten Doubles in [0.0, 1.0] niemals generiert werden.quelle
Der Artikel Javas neue Mathematik, Teil 2: Gleitkommazahlen von IBM bietet das folgende Codefragment, um dies zu lösen (in Gleitkommazahlen , aber ich vermute, dass es auch für Doppel funktioniert):
Sie haben diesen Kommentar dazu:
quelle
float
, nichtdouble
-float
s haben einen Bruchteil von 23 Bit, also2**23 -> 8388608
unterschiedliche Werte zwischen benachbarten Zweierpotenzen (der "inklusive" Teil bedeutet natürlich, dass Sie noch eine zählen müssen, die nächste Zweierpotenz).double
s haben 52-Bit-Brüche!double
Äquivalent und dachte "Hey, ich werde meine eigene Frage in ungefähr 5 Minuten beantworten ..."double
zwischen benachbarten Zweierpotenzen ungefähr 52 Tage dauern (dasprintln
wäre natürlich sehr unwahrscheinlich, so schnell zu laufen, egal was passiert) Nehmen wir an, dass eine Aussage weggeht ;-). Ich denke, es ist machbar, ein Jahr oder weniger auf einer leistungsstarken, aber realistischen Maschine zu verbringen ;-).Weitere Informationen finden Sie im Wikipedia-Artikel .
quelle
1
falsch ist , weil der versteckte Bit ist immer - also2^52
, nicht2^53
eindeutige Werte (zwischen benachbarten Potenzen von zwei, eines enthält und die nächsten ausgeschlossen - nicht ! Zwischen 0,0 und 1,0).Das Java-Double ist eine IEEE 754-Binärzahl64.
Dies bedeutet, dass wir Folgendes berücksichtigen müssen:
Dies bedeutet im Grunde, dass es insgesamt 2 ^ 62-2 ^ 52 + 1 mögliche Doppeldarstellungen gibt, die gemäß dem Standard zwischen 0 und 1 liegen. Beachten Sie, dass 2 ^ 52 + 1 dazu dient, die Fälle der nicht normalisierten zu entfernen Zahlen.
Denken Sie daran, dass wenn die Mantisse positiv ist, der Exponent jedoch negativ, die Zahl positiv ist, aber weniger als 1 :-)
Für andere Zahlen ist es etwas schwieriger, weil die Kanten-Ganzzahl-Zahlen in der IEEE 754-Darstellung möglicherweise nicht präzise darstellbar sind und weil im Exponenten andere Bits verwendet werden, um die Zahlen darstellen zu können. Je größer die Zahl, desto niedriger die verschiedenen Werte.
quelle