Gleitkommaformat mit doppelter Genauigkeit - Double-precision floating-point format

Das Gleitkommaformat mit doppelter Genauigkeit (manchmal auch als FP64 oder float64 bezeichnet ) ist ein Computerzahlenformat , das normalerweise 64 Bit im Computerspeicher belegt; es stellt einen breiten dynamischen Bereich von numerischen Werten durch ein schwebendes Verwendung radix Punkt .

Gleitkomma wird verwendet, um Bruchwerte darzustellen, oder wenn ein breiterer Bereich benötigt wird, als der Festkomma (mit der gleichen Bitbreite) bietet, selbst wenn dies auf Kosten der Genauigkeit geht. Doppelte Genauigkeit kann gewählt werden, wenn der Bereich oder die Genauigkeit der einfachen Genauigkeit nicht ausreichen würde.

Im Standard IEEE 754-2008 wird das 64-Bit-Base-2-Format offiziell als binary64 bezeichnet ; es wurde in IEEE 754-1985 doppelt genannt . IEEE 754 spezifiziert zusätzliche Gleitkommaformate, einschließlich 32-Bit-Basis-2- Einfachpräzision und neuerdings auch Basis-10-Darstellungen.

Eine der ersten Programmiersprachen , die Gleitkommadatentypen mit einfacher und doppelter Genauigkeit bereitstellte, war Fortran . Vor der weit verbreiteten Einführung von IEEE 754-1985 hingen die Darstellung und Eigenschaften von Gleitkomma-Datentypen vom Computerhersteller und Computermodell sowie von Entscheidungen der Programmiersprachen-Implementierer ab. Der Datentyp mit doppelter Genauigkeit von GW-BASIC war beispielsweise das 64-Bit-MBF- Gleitkommaformat.

Binäres Gleitkommaformat mit doppelter Genauigkeit nach IEEE 754: binary64

Binäres Gleitkomma mit doppelter Genauigkeit ist ein auf PCs häufig verwendetes Format, da es trotz seiner Leistungs- und Bandbreitenkosten einen größeren Bereich als Gleitkomma mit einfacher Genauigkeit aufweist. Es wird allgemein einfach als Doppel bezeichnet . Der IEEE 754-Standard spezifiziert ein binary64 mit:

Das Vorzeichenbit bestimmt das Vorzeichen der Zahl (einschließlich wenn diese Anzahl null ist , das ist , unterzeichnet ).

Das Exponentenfeld ist eine 11-Bit-Ganzzahl ohne Vorzeichen von 0 bis 2047 in vorgespannter Form : ein Exponentenwert von 1023 repräsentiert die tatsächliche Null. Exponenten reichen von −1022 bis +1023, da Exponenten von −1023 (alle 0) und +1024 (alle 1) für Sonderzahlen reserviert sind.

Die 53-Bit-Signifikand-Präzision ergibt eine Genauigkeit von 15 bis 17 signifikanten Dezimalstellen (2 −53  ≈ 1,11 × 10 −16 ). Wenn eine Dezimalzeichenfolge mit höchstens 15 signifikanten Stellen in eine IEEE 754-Darstellung mit doppelter Genauigkeit umgewandelt und dann wieder in eine Dezimalzeichenfolge mit derselben Anzahl von Stellen umgewandelt wird, sollte das Endergebnis mit der ursprünglichen Zeichenfolge übereinstimmen. Wenn eine IEEE 754-Zahl mit doppelter Genauigkeit in eine Dezimalzeichenfolge mit mindestens 17 signifikanten Stellen umgewandelt und dann wieder in eine Darstellung mit doppelter Genauigkeit umgewandelt wird, muss das Endergebnis mit der ursprünglichen Zahl übereinstimmen.

Das Format wird mit dem Signifikand geschrieben , der ein implizites Integer-Bit mit dem Wert 1 hat (außer bei Sonderdaten, siehe Exponentencodierung unten). Mit den 52 Bit des Bruchzeichens (F), die im Speicherformat erscheinen, beträgt die Gesamtgenauigkeit daher 53 Bit (ungefähr 16 Dezimalstellen, 53 log 10 (2) ≈ 15,955). Die Bits sind wie folgt angeordnet:

IEEE 754 Double Floating Point Format.svg

Der reelle Wert, der von einem gegebenen 64-Bit-Datum mit doppelter Genauigkeit mit einem gegebenen Bias-Exponenten und einem 52-Bit-Anteil angenommen wird, ist

oder

Zwischen 2 52 = 4.503.599.627.370.496 und 2 53 =9.007.199.254.740.992 sind die darstellbaren Zahlen genau die ganzen Zahlen. Für den nächsten Bereich von 2 53 bis 2 54 wird alles mit 2 multipliziert, sodass die darstellbaren Zahlen die geraden sind usw. Umgekehrt ist für den vorherigen Bereich von 2 51 bis 2 52 der Abstand 0,5 usw.

Der Abstand als Bruchteil der Zahlen im Bereich von 2 n bis 2 n +1 beträgt 2 n –52 . Der maximale relative Rundungsfehler beim Runden einer Zahl auf die nächste darstellbare Zahl (das Maschinenepsilon ) beträgt daher 2 −53 .

Die 11-Bit-Breite des Exponenten ermöglicht die Darstellung von Zahlen zwischen 10 –308 und 10 308 , mit voller Genauigkeit von 15–17 Dezimalstellen. Durch Kompromisse bei der Genauigkeit ermöglicht die subnormale Darstellung sogar noch kleinere Werte bis zu etwa 5 × 10 –324 .

Exponentencodierung

Der binäre Gleitkommaexponent mit doppelter Genauigkeit wird unter Verwendung einer Offset-Binär- Darstellung codiert , wobei der Null-Offset 1023 beträgt; im IEEE 754-Standard auch als Exponent-Bias bekannt. Beispiele für solche Darstellungen wären:

e = = =1: 00000000001200116 (kleinster Exponent für normale Zahlen )
e = = =1023: 0111111111123ff16 (Null-Offset)
e = = =1029: 10000000101240516
e = = =2046: 1111111111027fe16 (höchster Exponent)

Die Exponenten und haben eine besondere Bedeutung: 000167ff16

wobei F der Bruchteil des Signifikanten ist . Alle Bitmuster sind gültige Codierung.

Abgesehen von den oben genannten Ausnahmen wird die gesamte Zahl mit doppelter Genauigkeit beschrieben durch:

Bei Subnormalen ( e = 0) wird die Zahl mit doppelter Genauigkeit beschrieben durch:

Endianität

Obwohl die allgegenwärtigen x86-Prozessoren von heute Little-Endian-Speicher für alle Arten von Daten (Ganzzahl, Gleitkomma) verwenden, gibt es eine Reihe von Hardwarearchitekturen, bei denen Gleitkommazahlen in Big-Endian-Form dargestellt werden, während Ganzzahlen in Little-Endian-Form dargestellt werden. Endian-Form. Es gibt ARM- Prozessoren, die halb Little-Endian-, halb Big-Endian-Gleitkommadarstellung für Zahlen mit doppelter Genauigkeit haben: Beide 32-Bit-Wörter werden in Little-Endian-ähnlichen Integer-Registern gespeichert, aber das höchstwertige zuerst. Da es viele Gleitkommaformate ohne " Netzwerk "-Standarddarstellung für sie gab, verwendet der XDR- Standard Big-Endian-IEEE 754 als seine Darstellung. Es mag daher seltsam erscheinen, dass der weit verbreitete Gleitkomma-Standard IEEE 754 keine Endianness spezifiziert. Theoretisch bedeutet dies, dass selbst Standard-IEEE-Gleitkommadaten, die von einem Computer geschrieben wurden, von einem anderen möglicherweise nicht gelesen werden können. Auf modernen Standardcomputern (dh die IEEE 754) implementieren, kann man jedoch in der Praxis sicher annehmen, dass die Endianness für Gleitkommazahlen dieselbe ist wie für ganze Zahlen, was die Konvertierung unabhängig vom Datentyp unkompliziert macht. (Kleine eingebettete Systeme, die spezielle Gleitkommaformate verwenden, können jedoch eine andere Sache sein.)

VAX- Gleitkomma speichert Little-Endian-16-Bit-Wörter in Big-Endian-Reihenfolge.

Beispiele mit doppelter Genauigkeit

0 01111111111 0000000000000000000000000000000000000000000000000000 2 ≙ 3FF0 0000 0000 0000 16 ≙ +2 0 × 1 = 1
0 01111111111 000000000000000000000000000000000000000000000000000001 2 ≙ 3FF0 0000 0000 0001 16 ≙ +2 0 × (1 + 2 −52 ) ≈ 1.0000000000000002, kleinste Zahl > 1
0 01111111111 00000000000000000000000000000000000000000000000000010 2 ≙ 3FF0 0000 0000 0002 16 ≙ +2 0 × (1 + 2 −51 ) ≈ 1.0000000000000004
0 10000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 4000 0000 0000 0000 16 ≙ +2 1 × 1 = 2
1 10000000000 0000000000000000000000000000000000000000000000000000 2 ≙ C000 0000 0000 0000 16 ≙ −2 1 × 1 = −2
0 10000000000 1000000000000000000000000000000000000000000000000000 2 ≙ 4008 0000 0000 0000 16 ≙ +2 1 × 1,1 2 = 11 2 = 3
0 10000000001 0000000000000000000000000000000000000000000000000000 2 ≙ 4010 0000 0000 0000 16 ≙ +2 2 × 1 = 100 2 = 4
0 10000000001 0100000000000000000000000000000000000000000000000000 2 ≙ 4014 0000 0000 0000 16 ≙ +2 2 × 1,01 2 = 101 2 = 5
0 10000000001 1000000000000000000000000000000000000000000000000000 2 ≙ 4018 0000 0000 0000 16 ≙ +2 2 × 1,1 2 = 110 2 = 6
0 1000000011 01110000000000000000000000000000000000000000000000000 2 ≙ 4037 0000 0000 0000 16 ≙ +2 4 × 1.0111 2 = 10111 2 = 23
0 01111111000 1000000000000000000000000000000000000000000000000000 2 ≙ 3F88 0000 0000 0000 16 ≙ +2 −7 × 1,1 2 = 0,00000011 2 = 0,01171875 (3/256)
0 00000000000 000000000000000000000000000000000000000000000000000001 2 ≙ 0000 0000 0000 0001 16 ≙ +2 −1022 × 2 −52 = 2 −1074 ≈ 4.9406564584124654 × 10 −324 (Min. subnormal positives Doppel)
0 00000000000 11111111111111111111111111111111111111111111111111 2 ≙ 000F FFFF FFFF FFFF 16 ≙ +2 −1022 × (1 − 2 −52 ) ≈ 2,2250738585072009 × 10 −308 (Max. Subnormal Double)
0 00000000001 0000000000000000000000000000000000000000000000000000 2 ≙ 0010 0000 0000 0000 16 ≙ +2 −1022 × 1 ≈ 2,2250738585072014 × 10 −308 (Min. normal positiv doppelt)
0 11111111110 11111111111111111111111111111111111111111111111111111 2 ≙ 7FEF FFFF FFFF FFFF 16 ≙ +2 1023 × (1 + (1 − 2 −52 )) ≈ 1,7976931348623157 × 10 308 (Max. Double)
0 00000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 0000 0000 0000 0000 16 ≙ +0
1 00000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 8000 0000 0000 0000 16 ≙ −0
0 111111111111 0000000000000000000000000000000000000000000000000000 2 ≙ 7FF0 0000 0000 0000 16 ≙ +∞ (positiv unendlich)
1 111111111111 0000000000000000000000000000000000000000000000000000 2 ≙ FFF0 0000 0000 0000 16 ≙ −∞ (negativ unendlich)
0 11111111111 000000000000000000000000000000000000000000000000000001 2 ≙ 7FF0 0000 0000 0001 16 ≙ NaN (sNaN auf den meisten Prozessoren wie x86 und ARM)
0 11111111111 100000000000000000000000000000000000000000000000000001 2 ≙ 7FF8 0000 0000 0001 16 ≙ NaN (qNaN auf den meisten Prozessoren wie x86 und ARM)
0 11111111111 11111111111111111111111111111111111111111111111111 2 ≙ 7FFF FFFF FFFF FFFF 16 ≙ NaN (eine alternative Kodierung von NaN)
0 01111111101 0101010101010101010101010101010101010101010101010101 2 = 3FD5 5555 5555 5555 16 ≙ +2 −2 × (1 + 2 −2 + 2 −4 + ... + 2 −52 ) ≈ 1 / 3
0 10000000000 1001001000011111101101010100010001000010110100011000 2 = 4009 21FB 5444 2D18 16 ≈ pi

Kodierungen von qNaN und sNaN sind in IEEE 754 nicht vollständig spezifiziert und abhängig vom Prozessor. Die meisten Prozessoren, wie z. B. die Prozessoren der x86- Familie und der ARM- Familie, verwenden das höchstwertige Bit des Signifikand-Feldes, um ein ruhiges NaN anzuzeigen; dies wird von IEEE 754 empfohlen. Die PA-RISC- Prozessoren verwenden das Bit, um eine Signalisierungs-NaN anzuzeigen.

Standardmäßig 1 / 3 Runde nach unten, statt nach oben , wie mit einfacher Genauigkeit , aufgrund der ungeraden Anzahl von Bits in der Mantisse.

Ausführlicher:

Given the hexadecimal representation 3FD5 5555 5555 555516,
  Sign = 0
  Exponent = 3FD16 = 1021
  Exponent Bias = 1023 (constant value; see above)
  Fraction = 5 5555 5555 555516
  Value = 2(Exponent − Exponent Bias) × 1.Fraction – Note that Fraction must not be converted to decimal here
        = 2−2 × (15 5555 5555 555516 × 2−52)
        = 2−54 × 15 5555 5555 555516
        = 0.333333333333333314829616256247390992939472198486328125
        ≈ 1/3

Ausführungsgeschwindigkeit mit Double-Precision-Arithmetik

Die Verwendung von Gleitkommavariablen mit doppelter Genauigkeit und mathematischen Funktionen (z. B. sin, cos, atan2, log, exp und sqrt) ist langsamer als die Arbeit mit ihren Gegenstücken mit einfacher Genauigkeit. Ein Bereich der Datenverarbeitung, in dem dies ein besonderes Problem darstellt, ist paralleler Code, der auf GPUs ausgeführt wird. Wenn Sie beispielsweise die CUDA- Plattform von NVIDIA verwenden , dauern Berechnungen mit doppelter Genauigkeit je nach Hardware etwa 2- bis 32-mal länger als Berechnungen mit einfacher Genauigkeit .

Genauigkeitsbeschränkungen für ganzzahlige Werte

  • Ganzzahlen von −2 53 bis 2 53 (−9.007.199.254.740.992 bis 9.007.199.254.740.992) können exakt dargestellt werden
  • Ganzzahlen zwischen 2 53 und 2 54 = 18.014.398.509.481.984 runden auf ein Vielfaches von 2 (gerade Zahl)
  • Ganzzahlen zwischen 2 54 und 2 55 = 36.028.797.018.963.968 runden auf ein Vielfaches von 4

Implementierungen

Doubles werden in vielen Programmiersprachen auf unterschiedliche Weise implementiert, z. B. wie folgt. Auf Prozessoren mit nur dynamischer Präzision, wie x86 ohne SSE2 (oder wenn SSE2 aus Kompatibilitätsgründen nicht verwendet wird) und mit erweiterter Präzision, die standardmäßig verwendet wird, kann die Software möglicherweise Schwierigkeiten haben, einige Anforderungen zu erfüllen.

C und C++

C und C++ bieten eine Vielzahl von arithmetischen Typen . Doppelte Genauigkeit wird von den Standards nicht gefordert (außer durch den optionalen Anhang F von C99 , der die IEEE 754-Arithmetik abdeckt), aber auf den meisten Systemen doubleentspricht der Typ der doppelten Genauigkeit. Auf 32-Bit-x86 mit standardmäßig erweiterter Genauigkeit entsprechen einige Compiler jedoch möglicherweise nicht dem C-Standard oder die Arithmetik kann unter doppelter Rundung leiden .

Fortran

Fortran bietet mehrere Integer- und Real-Typen, und der 64-Bit-Typ real64, auf den über das intrinsische Modul von Fortran zugegriffen werden kann iso_fortran_env, entspricht doppelter Genauigkeit.

Gemeinsame Lisp

Common Lisp bietet die Typen SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT und LONG-FLOAT an. Die meisten Implementierungen stellen SINGLE-FLOATs und DOUBLE-FLOATs mit den anderen Typen entsprechenden Synonymen bereit. Common Lisp bietet Ausnahmen zum Abfangen von Gleitkomma-Unterläufen und -Überläufen und die ungenaue Gleitkomma-Ausnahme gemäß IEEE 754. Im ANSI-Standard werden keine Unendlichkeiten und NaNs beschrieben, jedoch bieten einige Implementierungen diese als Erweiterungen an.

Java

Auf Java vor Version 1.2 musste jede Implementierung IEEE 754-kompatibel sein. Version 1.2 ermöglichte es Implementierungen, bei Zwischenberechnungen für Plattformen wie x87 zusätzliche Präzision zu erzielen . Daher wurde ein Modifikator strictfp eingeführt, um strenge IEEE 754-Berechnungen zu erzwingen. In Java 17 wurde ein strikter Gleitkommawert wiederhergestellt.

JavaScript

Wie vom ECMAScript- Standard spezifiziert , soll die gesamte Arithmetik in JavaScript mit Gleitkomma-Arithmetik mit doppelter Genauigkeit durchgeführt werden.

Siehe auch

  • IEEE 754 , IEEE-Standard für Gleitkomma-Arithmetik

Hinweise und Referenzen