Seite 1 von 1

Re: double - Datentyp

Verfasst: 20.07.2016, 13:53
von Schrompf
Schöner Fund, der ist wirklich gut!

Re: double - Datentyp

Verfasst: 20.07.2016, 13:54
von Spiele Programmierer
Hier scheint es ja erstaunlich viel gefährliches Halbwissen zu Gleitkommazahlen zu geben.
Alle Ganzzahlen von inklusive -2^53 bis 2^53 sind mit double exakt darstellbar. Ja - es ist mehr als ±2^52...

Jede Gleitkommazahl stellt eine Zahl wie folgt dar:
Vorzeichen * Mantisse * 2^Exponent
  • Das Vorzeichen verwendet immer ein Bit und entweder +1 oder -1. (Sollte klar sein)
  • Die zur Mantisse verwendeten Bits stellen eine Zahl zwischen 1 und 2 dar. (!)
  • Die Mantissenwerte sind linear verteilt. Wäre die Mantisse 3 Bits groß, könnte die Mantisse folgende 8 Werte annehmen:
    1, 1.125, 1.25, 1.375, 1.5, 1.625, 1.75, 1.875
    Die Zahlen ergeben sich so:
    1, 1 + 2^-3, 1 + 2*2^-3, 1 + 3*2^-3, 1 + 4*2^-3, 1 + 5*2^-3, 1 + 6 * 2^-3, 1 + 7 * 2^-3 (= 2 - 2^-3)
  • Die verbleibenden Bits fallen an den Exponenten. (Der Exponent kann negativ sein - für Zahlen kleiner 1)
Für die Zahl 3 ist ist das Vorzeichen positiv, die Mantisse 1.5 und der Exponent 1:
+1 * 1.5 * 2^1 = 1.5 * 2 = 3
Bei double Zahlen ist für 2^53 - 1 ist die Mantisse 2 - 2^-52 (≈ 1.99999...). Und der Exponent 2^52:
+1 * (2-2^-52) * 2^1 = +1 * 1.999999... * 2^52 = 9007199254740991
2^53 geht auch noch - die Mantisse 1 ist exakt darstellbar:
+1 * 1 * 2^53 = 9007199254740992

Obwohl die Mantisse nur 52 Bits hat, sind die Zahlen bis 2^53 exakt darstellbar. Das liegt daran, dass die Mantissenwerte eben zwischen 1 und 2 liegen. Der Exponent ist somit 1 kleiner als im ersten Moment vlt. anzunehmen. Das Konzept nennt sich auch "Hidden Bit". Wäre das nicht so, gäbe es auch mehrere Möglichkeiten, die selbe Zahl darzustellen. (Das wären dann verschwendete Darstellungsweisen für sinnvolle Informationen)

Erst ab 2^53+1 gibt es Probleme, weil die Mantissenwerte nur 2^-52 auseinander liegen, der Exponent jetzt aber inzwischen bei 2^53 angelangt ist. Die nächste double Gleitkommazahl größer als 2^53, hat eine Mantisse um 2^-52 größer. Das ist dann:
+1 * (1+2^-52) * 2^53 = +1 * 1.000000... * 2^53 = 9007199254740994
9007199254740993 ist damit die erste natürliche Zahl, die nicht als Gleitkommazahlen doppelter Genauigkeit darstellbar ist.

Es gibt zwei Ausnahmen zu dieser Regel, dass die Mantisse eine Zahl zwischen 1 und 2 beschreibt. Und das sind die beiden Extremen, nahe 0 und sehr große Zahlen. Die sogenannten denormalisierten Gleitkommazahlen und die Unendlichkeit.
  • Denormalisierte Gleitkommazahlen sind eine Ausnahme um die 0 darstellen zu können. (außerdem ein paar andere sehr kleine Zahlen)
    Wenn der Exponent den minimalen Wert annimmt (bei double -1023), beschreibt die Mantisse eine Zahl den Bereich 0 bis 2! Dadurch wird die Null speicherbar (als 1 * 0 * 2^-1023). Das ist der Grund, warum die kleinste positive double Zahl nicht +1 * 1^-1023 ≈ 1.11*10^-308 ist, sondern +1 * 2^-51 * 2^-1023 ≈ 4.94*10^-324. Je nach Bibliothek und Programmiersprache gibt es unterschiedliche Ansichten, was denn nun die kleinste positive Gleitkommazahl ist. DBL_MIN in C(++) ist z.B. ~2.22e–308, obwohl es durchaus kleinere positive Zahlen gibt.
  • Unendlichkeiten sind eine Ausnahme um den Überlauf zu kennzeichnen.
    Wenn der Exponent den maximalen Wert annimmt (bei double 1024), ist der Wert unendlich. Mit dem Vorzeichenbit gibt es auch noch negativ unendlich. Die Mantisse ist ungenutzt. Falls ein Bit in der Mantisse gesetzt ist, wird die Zahl als Not a Number (NaN) interpretiert.
Ist es denn immer garantiert, das bei einem double-typ *ausschließlich* und *nur* die Mantisse zur darstellung verwendet wird, wenn die darzustellende Zahl kleiner als 2^52 ist?
Was stellst du dir darunter vor, "nur die Mantisse" zu verwenden? Eine Gleitkommazahl hat immer die 3 Teile gleicher Größe.

Re: double - Datentyp

Verfasst: 20.07.2016, 13:59
von xq
Danke! Ich war zu faul, das jetzt so ausführlich zu schreiben und kürzer ist es irgendwie sinnlos :P