Gleitkommaarithmetik - Floating-point arithmetic

Ein früher elektromechanischer programmierbarer Computer, der Z3 , enthielt Gleitkomma-Arithmetik (Nachbau im Deutschen Museum in München ausgestellt ).

Beim Rechnen ist Gleitkommaarithmetik ( FP ) eine Arithmetik unter Verwendung der formelhaften Darstellung reeller Zahlen als Näherung, um einen Kompromiss zwischen Bereich und Genauigkeit zu unterstützen. Aus diesem Grund wird die Gleitkommaberechnung häufig in Systemen mit sehr kleinen und sehr großen reellen Zahlen verwendet, die schnelle Verarbeitungszeiten erfordern. Im Allgemeinen wird eine Gleitkommazahl ungefähr mit einer festen Anzahl von signifikanten Ziffern (dem Signifikand ) dargestellt und unter Verwendung eines Exponenten in einer festen Basis skaliert ; die Basis für die Skalierung ist normalerweise zwei, zehn oder sechzehn. Eine exakt darstellbare Zahl hat folgende Form:

wobei Signifikand eine ganze Zahl ist , base eine ganze Zahl größer oder gleich zwei ist und Exponent ebenfalls eine ganze Zahl ist. Zum Beispiel:

Der Begriff Gleitkomma bezieht sich auf die Tatsache, dass der Radixpunkt einer Zahl ( Dezimalpunkt , oder häufiger in Computern Binärpunkt ) "schweben" kann; das heißt, es kann an einer beliebigen Stelle relativ zu den signifikanten Stellen der Zahl platziert werden. Diese Position wird als Exponentenkomponente angegeben, und somit kann man sich die Gleitkommadarstellung als eine Art wissenschaftliche Notation vorstellen .

Ein Gleitkommasystem kann verwendet werden, um mit einer festen Anzahl von Ziffern Zahlen verschiedener Größenordnungen darzustellen : zB kann der Abstand zwischen Galaxien oder der Durchmesser eines Atomkerns mit derselben Längeneinheit ausgedrückt werden. Das Ergebnis dieses Dynamikbereichs ist, dass die darstellbaren Zahlen nicht gleichmäßig beabstandet sind; die Differenz zwischen zwei aufeinanderfolgenden darstellbaren Zahlen variiert mit der gewählten Skala.

Gleitkommazahlen einfacher Genauigkeit auf einem Zahlenstrahl : Die grünen Linien markieren darstellbare Werte.
Obige erweiterte Version, die beide Zeichen von darstellbaren Werten zeigt

Im Laufe der Jahre wurde eine Vielzahl von Gleitkommadarstellungen in Computern verwendet. 1985 wurde der IEEE 754- Standard für Gleitkomma-Arithmetik etabliert, und seit den 1990er Jahren sind die am häufigsten anzutreffenden Darstellungen die von der IEEE definierten.

Die Geschwindigkeit von Gleitkommaoperationen, üblicherweise in Form von FLOPS gemessen , ist ein wichtiges Merkmal eines Computersystems , insbesondere für Anwendungen, die intensive mathematische Berechnungen erfordern.

Eine Gleitkommaeinheit (FPU, umgangssprachlich ein mathematischer Koprozessor ) ist ein Teil eines Computersystems, das speziell für die Ausführung von Operationen mit Gleitkommazahlen entwickelt wurde.

Überblick

Gleitkommazahlen

Eine Zahlendarstellung gibt eine Art der Codierung einer Zahl an, normalerweise als Zeichenfolge.

Es gibt mehrere Mechanismen, mit denen Ziffernfolgen Zahlen darstellen können. In üblicher mathematischer Schreibweise kann die Ziffernfolge eine beliebige Länge haben, und die Position des Radixpunktes wird angezeigt, indem dort ein explizites "Punkt"-Zeichen (Punkt oder Komma) platziert wird. Wenn der Radixpunkt nicht angegeben wird, stellt die Zeichenfolge implizit eine ganze Zahl dar und der nicht angegebene Radixpunkt würde sich am rechten Ende der Zeichenfolge neben der niedrigstwertigen Ziffer befinden. Bei Festkommasystemen wird für den Radixpunkt eine Position im String angegeben. Ein Festkomma-Schema könnte also darin bestehen, eine Zeichenfolge von 8 Dezimalstellen mit dem Dezimalpunkt in der Mitte zu verwenden, wobei "00012345" 0001.2345 darstellen würde.

In der wissenschaftlichen Notation wird die angegebene Zahl mit einer Potenz von 10 skaliert , sodass sie in einem bestimmten Bereich liegt – typischerweise zwischen 1 und 10, wobei der Radix-Punkt unmittelbar nach der ersten Ziffer erscheint. Der Skalierungsfaktor als Zehnerpotenz wird dann separat am Ende der Zahl angegeben. Zum Beispiel kann die Umlaufzeit von Jupiter ‚s Mond Io ist152.853,5047 Sekunden, ein Wert, der in wissenschaftlicher Standardschreibweise als1,528535047 × 10 5 Sekunden.

Die Gleitkommadarstellung ähnelt im Konzept der wissenschaftlichen Notation. Logischerweise besteht eine Gleitkommazahl aus:

  • Eine vorzeichenbehaftete (also positive oder negative) Ziffernfolge einer bestimmten Länge in einer bestimmten Basis (oder Radix ). Diese Ziffernfolge wird als Signifikand , Mantisse oder Koeffizient bezeichnet . Die Länge des Signifikanten bestimmt die Genauigkeit, mit der Zahlen dargestellt werden können. Es wird davon ausgegangen, dass die Position des Radixpunkts immer irgendwo innerhalb des Signifikanten liegt – oft kurz nach oder kurz vor der höchstwertigen Stelle oder rechts von der am weitesten rechts (niedrigstwertigen) Stelle. Dieser Artikel folgt im Allgemeinen der Konvention, dass der Radixpunkt direkt nach der höchstwertigen Stelle (ganz links) gesetzt wird.
  • Ein ganzzahliger Exponent mit Vorzeichen (auch als Merkmal oder Skala bezeichnet ), der die Größe der Zahl ändert.

Um den Wert der Gleitkommazahl abzuleiten, wird der Signifikand mit der mit dem Exponenten potenzierten Basis multipliziert , was einer Verschiebung des Radixpunktes von seiner implizierten Position um eine Anzahl Stellen gleich dem Wert des Exponenten entspricht – auf nach rechts, wenn der Exponent positiv ist, oder nach links, wenn der Exponent negativ ist.

Am Beispiel der Basis 10 (der bekannten Dezimalschreibweise ) wird die Zahl152,853,5047 , die eine Genauigkeit von zehn Dezimalstellen hat, wird als Signifikand dargestellt1.528.535.047 zusammen mit 5 als Exponent. Um den tatsächlichen Wert zu ermitteln, wird ein Dezimalpunkt hinter die erste Ziffer des Signifikanden gesetzt und das Ergebnis mit 10 5 multipliziert , um zu erhalten1,528535047 × 10 5 , oder152.853,5047 . Beim Speichern einer solchen Nummer braucht die Basis (10) nicht gespeichert zu werden, da sie für den gesamten Bereich unterstützter Nummern gleich ist und somit abgeleitet werden kann.

Symbolisch ist dieser Endwert:

Dabei ist s der Signifikand (ohne Berücksichtigung eines implizierten Dezimalpunkts), p ist die Genauigkeit (die Anzahl der Stellen im Signifikand), b ist die Basis (in unserem Beispiel ist dies die Zahl zehn ) und e ist der Exponent.

Historisch wurden mehrere Zahlenbasen für die Darstellung von Gleitkommazahlen verwendet, wobei die Basis zwei ( binär ) am häufigsten ist, gefolgt von der Basis zehn ( dezimaler Gleitkomma ) und anderen weniger verbreiteten Varianten, wie der Basis sechzehn ( hexadezimaler Gleitkomma). ), Basis 8 (oktaler Gleitkomma), Basis 4 (quaternärer Gleitkomma), Basis 3 ( ausgeglichener ternärer Gleitkomma ) und gerade Basis 256 und Basis65.536 .

Eine Gleitkommazahl ist eine rationale Zahl , da sie als eine ganze Zahl geteilt durch eine andere dargestellt werden kann; zum Beispiel1,45 × 10 3 ist (145/100) × 1000 oder145.000 /100. Die Basis bestimmt die darstellbaren Brüche; zum Beispiel kann 1/5 nicht exakt als Gleitkommazahl mit einer Binärbasis dargestellt werden, aber 1/5 kann genau mit einer Dezimalbasis dargestellt werden (0,2 , oder2 × 10 –1 ). 1/3 kann jedoch weder binär (0.010101...) noch dezimal (0.333...) exakt dargestellt werden, aber zur Basis 3 ist es trivial (0,1 oder 1×3 −1 ) . Die Gelegenheiten, bei denen unendliche Ausdehnungen auftreten, hängen von der Basis und ihren Primfaktoren ab .

Die Art und Weise, wie Signifikand (einschließlich seines Vorzeichens) und Exponent in einem Computer gespeichert werden, ist implementierungsabhängig. Die gängigen IEEE-Formate werden später und an anderer Stelle ausführlich beschrieben, aber als Beispiel in der binären Gleitkommadarstellung mit einfacher Genauigkeit (32 Bit) , und somit ist der Signifikand ein String von 24 Bits . Zum Beispiel sind die ersten 33 Bit der Zahl π :

Lassen Sie uns in dieser binären Erweiterung die Positionen von 0 (am weitesten links oder höchstwertiges Bit) bis 32 (am weitesten rechts befindliches Bit) bezeichnen. Der 24-Bit-Signifikand stoppt an Position 23, dargestellt als unterstrichenes Bit0 oben. Das nächste Bit an der Position 24 wird die genannte Rundungsbit oder Rundungsbit . Es wird verwendet, um die 33-Bit-Näherung auf die nächste 24-Bit-Zahl zu runden (es gibt spezielle Regeln für Halbwerte , was hier nicht der Fall ist). Dieses Bit, das ist1 in diesem Beispiel wird zu der Ganzzahl addiert, die aus den 24 ganz links liegenden Bits gebildet wird, was Folgendes ergibt:

Wenn dies unter Verwendung der IEEE 754-Kodierung im Speicher gespeichert wird, wird dies zum Signifikand s . Es wird angenommen, dass der Signifikand einen Binärpunkt rechts vom ganz linken Bit hat. Die binäre Darstellung von π wird also von links nach rechts wie folgt berechnet:

wobei p die Genauigkeit ist (24 in diesem Beispiel), n ist die Position des Bits des Signifikanten von links (beginnend bei0 und Ende bei23 hier) und e ist der Exponent (1 in diesem Beispiel).

Es kann verlangt werden, dass die höchstwertige Ziffer des Signifikanten einer Zahl ungleich Null ist (außer wenn der entsprechende Exponent kleiner als der minimale wäre). Dieser Vorgang wird als Normalisierung bezeichnet . Für Binärformate (die nur die Ziffern verwenden0 und1 ), diese Ziffer ungleich Null ist notwendigerweise1 . Daher muss es nicht im Speicher dargestellt werden; Dadurch erhält das Format noch ein bisschen mehr Präzision. Diese Regel wird verschiedentlich als führende Bitkonvention , implizite Bitkonvention , versteckte Bitkonvention oder angenommene Bitkonvention bezeichnet .

Alternativen zu Gleitkommazahlen

Die Gleitkommadarstellung ist bei weitem die gebräuchlichste Art, in Computern eine Annäherung an reelle Zahlen darzustellen. Es gibt jedoch Alternativen:

  • Die Festkommadarstellung verwendet ganzzahlige Hardwareoperationen, die durch eine Softwareimplementierung einer bestimmten Konvention über die Position des Binär- oder Dezimalpunkts gesteuert werden, beispielsweise 6 Bits oder Ziffern von rechts. Die Hardware zum Manipulieren dieser Darstellungen ist weniger kostspielig als Gleitkommazahlen und kann auch verwendet werden, um normale Integer-Operationen durchzuführen. Binärer Festpunkt wird normalerweise in Spezialanwendungen auf eingebetteten Prozessoren verwendet, die nur ganzzahlige Arithmetik ausführen können, aber dezimaler Festpunkt ist in kommerziellen Anwendungen üblich.
  • Logarithmische Zahlensysteme (LNSs) repräsentieren eine reelle Zahl durch den Logarithmus ihres Absolutwertes und eines Vorzeichenbits. Die Werteverteilung ähnelt der Gleitkomma-Verteilung, aber die Wert-zu-Darstellungs-Kurve ( dh der Graph der Logarithmusfunktion) ist glatt (außer bei 0). Im Gegensatz zur Gleitkommaarithmetik sind in einem logarithmischen Zahlensystem Multiplikation, Division und Potenzierung einfach zu implementieren, aber Addition und Subtraktion sind komplex. Die ( symmetrische ) Level-Index-Arithmetik (LI und SLI) von Charles Clenshaw, Frank Olver und Peter Turner ist ein Schema, das auf einer verallgemeinerten Logarithmus- Darstellung basiert .
  • Verjüngte Gleitkommadarstellung , die in der Praxis anscheinend nicht verwendet wird.
  • Wo eine höhere Genauigkeit gewünscht wird, kann Gleitkommaarithmetik (typischerweise in Software) mit Signifikanten variabler Länge (und manchmal Exponenten) implementiert werden, deren Größe je nach tatsächlichem Bedarf und je nachdem, wie die Berechnung fortschreitet, bemessen werden. Dies wird als Gleitkommaarithmetik mit beliebiger Genauigkeit bezeichnet .
  • Gleitkomma-Erweiterungen sind eine weitere Möglichkeit, eine höhere Genauigkeit zu erzielen und von der Gleitkomma-Hardware zu profitieren: Eine Zahl wird als unbewertete Summe mehrerer Gleitkommazahlen dargestellt. Ein Beispiel ist die Doppel-Doppel-Arithmetik , die manchmal für den C-Typ verwendet wird long double.
  • Einige einfache rationale Zahlen ( zB 1/3 und 1/10) können nicht exakt in binären Gleitkommazahlen dargestellt werden, unabhängig von der Genauigkeit. Die Verwendung eines anderen Radix ermöglicht es, einige von ihnen darzustellen ( zB 1/10 in dezimaler Gleitkommazahl), aber die Möglichkeiten bleiben begrenzt. Softwarepakete, die rationale Arithmetik durchführen, stellen Zahlen als Brüche mit ganzzahligem Zähler und Nenner dar und können daher jede rationale Zahl exakt darstellen. Solche Pakete müssen im Allgemeinen " bignum " -Arithmetik für die einzelnen Ganzzahlen verwenden.
  • Die Intervallarithmetik ermöglicht es, Zahlen als Intervalle darzustellen und garantierte Ergebnisgrenzen zu erhalten. Sie basiert im Allgemeinen auf anderen Arithmetiken, insbesondere auf Gleitkommazahlen.
  • Computeralgebrasysteme wie Mathematica , Maxima und Maple können oft irrationale Zahlen wie oder auf eine vollständig "formale" Weise handhaben , ohne sich mit einer bestimmten Kodierung des Signifikanten zu befassen. Ein solches Programm kann Ausdrücke wie " " exakt auswerten , da es so programmiert ist, dass es die zugrunde liegende Mathematik direkt verarbeitet, anstatt für jede Zwischenrechnung Näherungswerte zu verwenden.

Geschichte

Im Jahr 1914 Leonardo Torres Quevedo entwickelt , um eine elektromechanische Version von Charles Babbage ‚s Analytical Engine und enthielt Gleitkomma-Arithmetik. 1938 stellte Konrad Zuse aus Berlin den Z1 fertig , den ersten binären, programmierbaren mechanischen Computer ; es verwendet eine binäre 24-Bit-Gleitkommazahldarstellung mit einem 7-Bit-Exponenten mit Vorzeichen, einem 17-Bit-Signifikanten (einschließlich eines impliziten Bits) und einem Vorzeichenbit. Das zuverlässigere, auf Relais basierende Z3 , das 1941 fertiggestellt wurde, hat Darstellungen für positive und negative Unendlichkeiten; insbesondere implementiert es definierte Operationen mit unendlich, wie zum Beispiel , und es stoppt bei undefinierten Operationen, wie zum Beispiel .

Konrad Zuse , Architekt des Z3- Computers, der eine binäre 22-Bit-Gleitkommadarstellung verwendet

Zuse schlug auch eine sorgfältig gerundete Gleitkomma-Arithmetik vor, die NaN-Darstellungen einschließt, aber nicht vollständig, und nahm die Merkmale des IEEE-Standards um vier Jahrzehnte vorweg. Im Gegensatz dazu empfahl von Neumann Gleitkommazahlen für die IAS-Maschine von 1951 und argumentierte, dass Festkommaarithmetik vorzuziehen sei.

Der erste kommerzielle Computer mit Gleitkomma-Hardware war der Z4- Computer von Zuse , der 1942-1945 entwickelt wurde. 1946 führten Bell Laboratories den Mark V ein, der dezimale Gleitkommazahlen implementierte .

Der Pilot ACE verfügt über binäre Gleitkomma-Arithmetik und wurde 1950 im National Physical Laboratory, Großbritannien, in Betrieb genommen . Dreiunddreißig wurden später als English Electric DEUCE kommerziell verkauft . Die Arithmetik ist tatsächlich in Software implementiert, aber mit einer Taktrate von einem Megahertz waren die Geschwindigkeiten von Gleitkomma- und Festkomma-Operationen in dieser Maschine anfangs schneller als die von vielen konkurrierenden Computern.

1954 folgte die massenproduzierte IBM 704 ; es führte die Verwendung eines voreingenommenen Exponenten ein . Für viele Jahrzehnte danach war Gleitkomma-Hardware typischerweise eine optionale Funktion, und Computer, die diese hatten, wurden als "wissenschaftliche Computer" bezeichnet oder " wissenschaftliche Berechnungen " (SC) haben (siehe auch Extensions for Scientific Computation (XSC .). )). Erst mit der Einführung des Intel i486 im Jahr 1989 verfügten Allzweck- PCs standardmäßig über Gleitkommafähigkeit in der Hardware.

Die 1962 eingeführte UNIVAC 1100/2200-Serie unterstützte zwei Gleitkommadarstellungen:

  • Einfache Genauigkeit : 36 Bit, organisiert als 1-Bit-Vorzeichen, 8-Bit-Exponent und 27-Bit-Signifikand.
  • Doppelte Genauigkeit : 72 Bit, organisiert als 1-Bit-Zeichen, 11-Bit-Exponent und 60-Bit-Signifikand.

Die ebenfalls 1962 eingeführte IBM 7094 unterstützt Darstellungen mit einfacher und doppelter Genauigkeit, jedoch ohne Bezug zu den Darstellungen der UNIVAC. Tatsächlich führte IBM 1964 hexadezimale Gleitkommadarstellungen in seinen System/360- Mainframes ein; Dieselben Darstellungen sind immer noch für die Verwendung in modernen z/Architecture- Systemen verfügbar. 1998 fügte IBM jedoch eine IEEE-kompatible binäre Gleitkomma-Arithmetik in seine Mainframes ein; 2005 fügte IBM auch eine IEEE-kompatible dezimale Gleitkomma-Arithmetik hinzu.

Anfangs verwendeten Computer viele verschiedene Darstellungen für Gleitkommazahlen. Der Mangel an Standardisierung auf Mainframe-Ebene war in den frühen 1970er Jahren ein anhaltendes Problem für diejenigen, die Quellcode auf höherer Ebene schreiben und pflegen; diese Hersteller-Gleitkomma-Standards unterschieden sich in Wortgrößen, Darstellungen, Rundungsverhalten und allgemeiner Genauigkeit der Operationen. Die Gleitkomma-Kompatibilität über mehrere Computersysteme musste in den frühen 1980er Jahren dringend standardisiert werden, was zur Schaffung des IEEE 754- Standards führte, als das 32-Bit- (oder 64-Bit-) Wort alltäglich geworden war. Dieser Standard basierte maßgeblich auf einem Vorschlag von Intel, das den numerischen Coprozessor i8087 entwarf ; Motorola, das ungefähr zur gleichen Zeit den 68000 entwarf , leistete ebenfalls einen wichtigen Beitrag.

1989 wurde der Mathematiker und Informatiker William Kahan mit dem Turing Award als Hauptarchitekt hinter diesem Vorschlag ausgezeichnet; er wurde von seinem Studenten (Jerome Coonen) und einem Gastprofessor (Harold Stone) unterstützt.

Zu den x86-Innovationen gehören diese:

  • Eine genau spezifizierte Gleitkommadarstellung auf Bit-String-Ebene, damit alle konformen Computer Bitmuster gleich interpretieren. Dies ermöglicht die genaue und effiziente Übertragung von Gleitkommazahlen von einem Computer auf einen anderen (nach Berücksichtigung der Endianness ).
  • Ein genau spezifiziertes Verhalten der Rechenoperationen: Es soll ein Ergebnis erzeugt werden, als ob durch unendlich genaue Arithmetik ein Wert erhalten würde, der dann nach bestimmten Regeln gerundet wird. Dies bedeutet, dass ein konformes Computerprogramm bei einer bestimmten Eingabe immer das gleiche Ergebnis liefern würde, wodurch der fast mystische Ruf gemildert wird, den die Gleitkommaberechnung für ihr bisher scheinbar nicht deterministisches Verhalten entwickelt hatte.
  • Die Fähigkeit von außergewöhnlichen Bedingungen (Überlauf, Division durch Null usw.), sich auf eine gutartige Weise durch eine Berechnung auszubreiten und dann von der Software kontrolliert behandelt zu werden.

Bereich von Gleitkommazahlen

Eine Gleitkommazahl besteht aus zwei Festkommakomponenten , deren Reichweite ausschließlich von der Anzahl der Bits bzw. Stellen in ihrer Darstellung abhängt. Während Komponenten linear von ihrem Bereich abhängen, hängt der Gleitkommabereich linear vom signifikanten Bereich und exponentiell vom Bereich der Exponentenkomponente ab, was der Zahl einen außergewöhnlich größeren Bereich beifügt.

Auf einem typischen Computersystem hat eine binäre Gleitkommazahl mit doppelter Genauigkeit (64 Bit) einen Koeffizienten von 53 Bit (einschließlich 1 implizierten Bit), einen Exponenten von 11 Bit und 1 Vorzeichenbit. Da 2 10 = 1024 ist, reicht der gesamte Bereich der positiven normalen Gleitkommazahlen in diesem Format von 2 −1022  ≈ 2 × 10 −308 bis ungefähr 2 1024  ≈ 2 × 10 308 .

Die Anzahl der normalisierten Gleitkommazahlen in einem System ( B , P , L , U ) wobei

  • B ist die Basis des Systems,
  • P ist die Genauigkeit des Signifikanten (in Basis B ),
  • L ist der kleinste Exponent des Systems,
  • U ist der größte Exponent des Systems,

ist .

Es gibt eine kleinste positive normalisierte Gleitkommazahl,

Unterlaufniveau = UFL = ,

die eine 1 als führende Ziffer und eine 0 für die restlichen Ziffern des Signifikanden und den kleinstmöglichen Wert für den Exponenten hat.

Es gibt eine größte Gleitkommazahl,

Überlaufpegel = OFL = ,

die B − 1 als Wert für jede Stelle des Signifikanten und den größtmöglichen Wert für den Exponenten hat.

Darüber hinaus gibt es darstellbare Werte streng zwischen −UFL und UFL. Nämlich positive und negative Nullen sowie denormalisierte Zahlen .

IEEE 754: Gleitkomma in modernen Computern

Die IEEE standardisierte 1985 die Computerdarstellung für binäre Gleitkommazahlen in IEEE 754 (auch bekannt als IEC 60559). Diesem ersten Standard folgen fast alle modernen Maschinen. Es wurde 2008 überarbeitet . IBM Mainframes unterstützen zusätzlich zum Binärformat IEEE 754 das IBM-eigene hexadezimale Gleitkommaformat und das dezimale Gleitkommaformat IEEE 754-2008 . Die Cray T90- Serie hatte eine IEEE-Version, aber der SV1 verwendet immer noch das Cray-Gleitkommaformat.

Der Standard sieht viele eng verwandte Formate vor, die sich nur in wenigen Details unterscheiden. Fünf dieser Formate werden als Basisformate bezeichnet , andere werden als Formate mit erweiterter Genauigkeit und Format mit erweiterbarer Genauigkeit bezeichnet . Drei Formate werden in Computerhardware und -sprachen besonders häufig verwendet:

  • Einfache Genauigkeit (binary32), die normalerweise verwendet wird, um den Typ "float" in der C-Sprachfamilie darzustellen (obwohl dies nicht garantiert ist ). Dies ist ein binäres Format, das 32 Bit (4 Byte) belegt und dessen Signifikand eine Genauigkeit von 24 Bit (ca. 7 Dezimalstellen) hat.
  • Doppelte Genauigkeit (binary64), die normalerweise verwendet wird, um den Typ "double" in der C-Sprachfamilie darzustellen (obwohl dies nicht garantiert ist ). Dies ist ein binäres Format, das 64 Bit (8 Byte) belegt und dessen Signifikand eine Genauigkeit von 53 Bit (ca. 16 Dezimalstellen) hat.
  • Double Extended , auch mehrdeutig als "erweiterte Präzision" bezeichnet. Dies ist ein binäres Format, das mindestens 79 Bit (80, wenn die Regel für versteckte/implizite Bits nicht verwendet wird) belegt und dessen Signifikand eine Genauigkeit von mindestens 64 Bit (ca. 19 Dezimalstellen) hat. Die Standards C99 und C11 der C-Sprachfamilie empfehlen in ihrem Annex F ("IEC 60559 Gleitkommaarithmetik") ein solches erweitertes Format als " long double " bereitzustellen . Ein Format, das die minimalen Anforderungen (64-Bit-Signifikanz, 15-Bit-Exponent, also passend auf 80 Bit) erfüllt, bietet die x86- Architektur. Auf solchen Prozessoren kann dieses Format oft mit "long double" verwendet werden, obwohl erweiterte Präzision mit MSVC nicht verfügbar ist. Zu Ausrichtungszwecken speichern viele Tools diesen 80-Bit-Wert in einem 96-Bit- oder 128-Bit-Bereich. Auf anderen Prozessoren kann "long double" für ein größeres Format stehen, wie z. B. vierfache Genauigkeit oder einfach nur doppelte Genauigkeit, wenn keine Form der erweiterten Genauigkeit verfügbar ist.

Das Erhöhen der Genauigkeit der Gleitkommadarstellung verringert im Allgemeinen den Betrag des akkumulierten Rundungsfehlers , der durch Zwischenberechnungen verursacht wird. Zu den weniger verbreiteten IEEE-Formaten gehören:

  • Vierfache Genauigkeit (binär 128). Dies ist ein binäres Format, das 128 Bit (16 Byte) belegt und dessen Signifikanz eine Genauigkeit von 113 Bit (ca. 34 Dezimalstellen) hat.
  • Decimal64- und Decimal128- Gleitkommaformate. Diese Formate sind zusammen mit dem decimal32- Format für die korrekte Ausführung von Dezimalrunden vorgesehen.
  • Half Precision , auch Binary16 genannt, ein 16-Bit-Gleitkommawert. Es wird in der NVIDIA Cg- Grafiksprache und im openEXR-Standard verwendet.

Jede ganze Zahl mit einem Absolutwert von weniger als 2 24 kann im Format mit einfacher Genauigkeit genau dargestellt werden, und jede ganze Zahl mit einem Absolutwert von weniger als 2 53 kann im Format mit doppelter Genauigkeit genau dargestellt werden. Darüber hinaus kann ein großer Bereich von Potenzen des 2-fachen einer solchen Zahl dargestellt werden. Diese Eigenschaften werden manchmal für rein ganzzahlige Daten verwendet, um 53-Bit-Ganzzahlen auf Plattformen zu erhalten, die Gleitkommazahlen mit doppelter Genauigkeit, aber nur 32-Bit-Ganzzahlen haben.

Der Standard spezifiziert einige spezielle Werte und ihre Darstellung: positive Unendlichkeit (+∞), negative Unendlichkeit (−∞), eine negative Null (−0) verschieden von gewöhnlichen ("positiven") Nullen und "keine Zahl"-Werte ( NaN ).

Der Vergleich von Gleitkommazahlen, wie er im IEEE-Standard definiert ist, unterscheidet sich etwas vom üblichen Ganzzahlvergleich. Negative und positive Null sind gleich, und jedes NaN vergleicht ungleich mit jedem Wert, einschließlich sich selbst. Alle endlichen Gleitkommazahlen sind strikt kleiner als +∞ und strikt größer als −∞, und sie sind genauso geordnet wie ihre Werte (in der Menge der reellen Zahlen).

Interne Vertretung

Gleitkommazahlen werden typischerweise als Vorzeichenbit, Exponentenfeld und Signifikand oder Mantisse von links nach rechts in ein Computerdatum gepackt. Für die IEEE 754-Binärformate (Basic und Extended), die über vorhandene Hardware-Implementierungen verfügen, werden sie wie folgt aufgeteilt:

Typ Unterschrift Exponent Bedeutungsfeld Gesamtbits Exponenten-Bias Bit-Präzision Anzahl Dezimalstellen
Hälfte ( IEEE 754-2008 ) 1 5 10 16 fünfzehn 11 ~3.3
Einzel 1 8 23 32 127 24 ~7.2
Doppelt 1 11 52 64 1023 53 ~15,9
x86 erweiterte Präzision 1 fünfzehn 64 80 16383 64 ~19,2
Quad 1 fünfzehn 112 128 16383 113 ~34,0

Während der Exponent positiv oder negativ sein kann, wird er in Binärformaten als vorzeichenlose Zahl gespeichert, der ein fester "Bias" hinzugefügt wird. Werte aller Nullen in diesem Feld sind für die Nullen und subnormalen Zahlen reserviert ; Werte aller Einsen sind für die Unendlichkeiten und NaNs reserviert. Der Exponentenbereich für normalisierte Zahlen beträgt [−126, 127] für einfache Genauigkeit, [−1022, 1023] für doppelte oder [−16382, 16383] für quad. Normalisierte Zahlen schließen subnormale Werte, Nullen, Unendlichkeiten und NaNs aus.

In den binären IEEE-Austauschformaten wird das führende 1-Bit eines normalisierten Signifikanden nicht tatsächlich im Computerdatum gespeichert. Es wird als "verstecktes" oder "implizites" Bit bezeichnet. Aus diesem Grund hat das Format mit einfacher Genauigkeit tatsächlich einen Signifikand mit 24 Bit Genauigkeit, das Format mit doppelter Genauigkeit hat 53 und Quad hat 113.

Zum Beispiel wurde oben gezeigt, dass π, auf 24 Bit Genauigkeit gerundet, hat:

  • Vorzeichen = 0 ; e = 1 ; s = 110010010000111111011011 (einschließlich des versteckten Bits)

Die Summe des Exponenten-Bias (127) und des Exponenten (1) beträgt 128, also wird dies im Format einfacher Genauigkeit dargestellt als

  • 0 10000000 10010010000111111011011 (ohne das versteckte Bit) = 40490FDB als hexadezimale Zahl.

Ein Beispiel für ein Layout für 32-Bit-Gleitkomma ist

Float-Beispiel.svg

und das 64-Bit-Layout ist ähnlich .

Sonderwerte

Vorzeichen Null

Im IEEE 754-Standard ist Null vorzeichenbehaftet, was bedeutet, dass es sowohl eine "positive Null" (+0) als auch eine "negative Null" (–0) gibt. In den meisten Laufzeitumgebungen wird die positive Null normalerweise als " 0" und die negative Null als " -0" ausgegeben . Die beiden Werte verhalten sich in numerischen Vergleichen gleich, aber einige Operationen liefern unterschiedliche Ergebnisse für +0 und −0. Zum Beispiel gibt 1/(−0) negativ unendlich zurück, während 1/+0 positiv unendlich zurückgibt (so dass die Identität 1/(1/±∞) = ±∞ beibehalten wird). Andere übliche Funktionen mit einer Diskontinuität bei x = 0, die +0 und −0 unterschiedlich behandeln könnten, sind log ( x ), signum ( x ) und die Hauptquadratwurzel von y + xi für jede negative Zahl y . Wie bei jedem Näherungsschema können Operationen mit "negativer Null" gelegentlich zu Verwirrung führen. Beispielsweise impliziert in IEEE 754 x = y nicht immer 1/ x = 1/ y , da 0 = −0, sondern 1/0 ≠ 1/−0 .

Subnormale Zahlen

Subnormale Werte füllen die Unterlauflücke mit Werten, bei denen der absolute Abstand zwischen ihnen gleich ist wie bei benachbarten Werten direkt außerhalb der Unterlauflücke. Dies ist eine Verbesserung gegenüber der älteren Praxis, bei der nur Null in der Unterlauflücke vorhanden ist und bei der Unterlaufergebnisse durch Null ersetzt wurden (auf Null spülen).

Moderne Gleitkomma-Hardware verarbeitet normalerweise subnormale Werte (sowie normale Werte) und erfordert keine Softwareemulation für subnormale Werte.

Unendlichkeiten

Die Unendlichkeiten des erweiterten reellen Zahlenstrahls können in IEEE-Gleitkommadatentypen dargestellt werden, genau wie gewöhnliche Gleitkommawerte wie 1, 1,5 usw. Sie sind in keiner Weise Fehlerwerte, obwohl sie es oft (aber nicht immer, da es von der Rundung abhängt) als Ersatzwerte bei einem Überlauf verwendet. Bei einer Division-durch-Null-Ausnahme wird als exaktes Ergebnis eine positive oder negative Unendlichkeit zurückgegeben. Eine Unendlichkeit kann auch als Zahl eingeführt werden (wie das Makro "INFINITY" von C oder "∞", wenn die Programmiersprache diese Syntax zulässt).

IEEE 754 verlangt einen vernünftigen Umgang mit Unendlichkeiten, wie z

  • (+∞) + (+7) = (+∞)
  • (+∞) × (−2) = (−∞)
  • (+∞) × 0 = NaN – es gibt nichts sinnvolles zu tun

NaNs

IEEE 754 spezifiziert einen speziellen Wert namens "Not a Number" (NaN), der als Ergebnis bestimmter "ungültiger" Operationen zurückgegeben wird, wie z. B. 0/0, ∞×0 oder sqrt(–1). Im Allgemeinen werden NaNs propagiert, dh die meisten Operationen, die ein NaN beinhalten, führen zu einem NaN, obwohl Funktionen, die ein bestimmtes Ergebnis für einen bestimmten Gleitkommawert liefern würden, dies auch für NaNs tun, z. B. NaN ^ 0 = 1. Es gibt zwei Arten von NaNs: die standardmäßigen stillen NaNs und optional signalisierende NaNs. Eine Signalisierung von NaN in einer beliebigen arithmetischen Operation (einschließlich numerischer Vergleiche) wird bewirken, dass eine "ungültige Operation" -Ausnahme signalisiert wird.

Die vom Standard spezifizierte Darstellung von NaNs weist einige nicht spezifizierte Bits auf, die verwendet werden könnten, um den Typ oder die Fehlerquelle zu codieren; aber es gibt keinen Standard für diese Kodierung. Theoretisch könnten signalisierende NaNs von einem Laufzeitsystem verwendet werden, um nicht initialisierte Variablen zu kennzeichnen oder die Gleitkommazahlen mit anderen speziellen Werten zu erweitern, ohne die Berechnungen mit gewöhnlichen Werten zu verlangsamen, obwohl solche Erweiterungen nicht üblich sind.

Designgrundsätze nach IEEE 754

William Kahan . Ein Hauptarchitekt des Intel 80x87 Gleitkomma-Coprozessors und des IEEE 754 Gleitkomma-Standards.

Es ist ein weit verbreiteter Irrglaube, dass die hier diskutierten eher esoterischen Merkmale des IEEE 754-Standards, wie erweiterte Formate, NaN, Unendlichkeiten, Subnormale usw., nur für numerische Analysten oder für fortgeschrittene numerische Anwendungen von Interesse sind ; Tatsächlich ist das Gegenteil der Fall: Diese Funktionen wurden entwickelt, um numerisch unerfahrenen Programmierern sichere und robuste Standardeinstellungen zu bieten, zusätzlich zur Unterstützung anspruchsvoller numerischer Bibliotheken durch Experten. Der Schlüsseldesigner von IEEE 754, William Kahan, stellt fest, dass es falsch ist, "... [deem] Features des IEEE-Standards 754 für binäre Gleitkomma-Arithmetik, die... Die Tatsachen sind genau das Gegenteil. 1977 wurden diese Funktionen in den Intel 8087 integriert, um den größtmöglichen Markt zu bedienen... Fehleranalyse zeigt uns, wie man Gleitkomma-Arithmetik wie den IEEE-Standard 754 entwickelt, die mäßig tolerant gegenüber Well -bedeutet Unwissenheit unter Programmierern".

  • Die speziellen Werte wie unendlich und NaN stellen sicher, dass die Gleitkomma-Arithmetik algebraisch vollständig ist: Jede Gleitkomma-Operation erzeugt ein wohldefiniertes Ergebnis und löst – standardmäßig – keinen Maschinen-Interrupt oder Trap aus. Darüber hinaus wurde die Auswahl von Sonderwerten, die in Ausnahmefällen zurückgegeben werden, darauf ausgelegt, in vielen Fällen die richtige Antwort zu geben. Zum Beispiel unter IEEE 754 Arithmetik Kettenbrüche wie R(z) := 7 − 3/[z − 2 − 1/(z − 7 + 10/[z − 2 − 2/(z − 3)]) ] liefert bei allen Eingaben die richtige Antwort, da die Potentialteilung durch Null, zB für z = 3 , durch Angabe von +unendlich korrekt gehandhabt wird, so dass solche Ausnahmen sicher ignoriert werden können. Wie Kahan anmerkte, wäre die unbehandelte Falle nach einem Überlauf der Konvertierung von Gleitkomma zu 16-Bit-Ganzzahl, der den Verlust einer Ariane 5- Rakete verursachte , unter der standardmäßigen IEEE 754-Gleitkommarichtlinie nicht aufgetreten .
  • Subnormale Zahlen stellen sicher, dass für endliche Gleitkommazahlen x und y x − y = 0 genau dann gilt, wenn x = y, wie erwartet, was aber unter früheren Gleitkommadarstellungen nicht galt.
  • Zur Design-Grundlage des x87-80 -Bit-Formats bemerkt Kahan: „Dieses erweiterte Format ist so konzipiert, dass es mit vernachlässigbarem Geschwindigkeitsverlust für alle außer der einfachsten Arithmetik mit Gleitkomma- und Doppeloperanden verwendet werden kann. Es sollte beispielsweise verwendet werden für Scratch-Variablen in Schleifen, die Rekursionen wie Polynomauswertung, Skalarprodukte, Teil- und Kettenbrüche implementieren. Es verhindert oft einen vorzeitigen Über-/Unterlauf oder eine schwerwiegende lokale Löschung, die einfache Algorithmen verderben können". Berechnen von Zwischenergebnissen in einem erweiterten Format mit hohen Präzision und erweitert Exponenten hat Präzedenzfälle in der historischen Praxis der wissenschaftlichen Berechnung und bei der Gestaltung von wissenschaftlichen Taschenrechnern zB Hewlett-Packard ‚s Finanzrechner ausgeführt Arithmetik und Finanzfunktionen auf drei bedeutendere Dezimalzahlen als sie gespeichert oder angezeigt. Die Implementierung von erweiterter Präzision ermöglichte die einfache Entwicklung von Standard-Elementarfunktionsbibliotheken, die normalerweise mit hoher Geschwindigkeit Ergebnisse mit doppelter Genauigkeit innerhalb einer Einheit an letzter Stelle (ULP) lieferten .
  • Das korrekte Runden von Werten auf den nächsten darstellbaren Wert vermeidet systematische Verzerrungen bei Berechnungen und verlangsamt das Anwachsen von Fehlern. Das Runden von Verknüpfungen auf sogar beseitigt die statistische Verzerrung, die beim Addieren ähnlicher Zahlen auftreten kann.
  • Gezieltes Runden war als Hilfe bei der Überprüfung von Fehlergrenzen gedacht, beispielsweise in der Intervallarithmetik . Es wird auch bei der Implementierung einiger Funktionen verwendet.
  • Die mathematische Grundlage der Operationen, insbesondere korrektes Runden, erlaubt es, mathematische Eigenschaften nachzuweisen und Gleitkomma-Algorithmen wie 2Sum, Fast2Sum und Kahan-Summationsalgorithmus zu entwerfen, um zB die Genauigkeit zu verbessern oder arithmetische Unterprogramme mit mehreren Genauigkeiten relativ einfach zu implementieren.

Eine Eigenschaft der Formate mit einfacher und doppelter Genauigkeit besteht darin, dass ihre Kodierung es ermöglicht, sie ohne Verwendung von Gleitkomma-Hardware leicht zu sortieren. Ihre Bits interpretierten als eine Zweierkomplement- Ganzzahl bereits sortiert das Positive richtig, mit den Negativ umgekehrt. Mit einem xor , um das Vorzeichenbit für positive Werte und alle Bits für negative Werte umzukehren, werden alle Werte als vorzeichenlose Ganzzahlen (mit −0 < +0 ) sortierbar . Es ist unklar, ob diese Eigenschaft beabsichtigt ist.

Andere bemerkenswerte Gleitkommaformate

Neben den weit verbreiteten Standardformaten nach IEEE 754 werden in bestimmten domänenspezifischen Bereichen andere Gleitkommaformate verwendet oder verwendet.

  • Das Microsoft Binary Format (MBF) wurde für das Microsoft BASIC - Sprache Produkte entwickelt, darunter Microsofts erstes Produkt der Altair BASIC (1975), TRS-80 LEVEL II , CP / M 's MBASIC , IBM PC 5150 ' s BASICA , MS- DOS ‚s GW-BASIC und Quickbasic vor Version 4.00. QuickBASIC-Version 4.00 und 4.50 wechselten zu dem IEEE 754-1985-Format, können jedoch mithilfe der Befehlsoption /MBF auf das MBF-Format zurückgesetzt werden. MBF wurde auf einem simulierten Intel 8080 von Monte Davidoff , einem Mitbewohner von Bill Gates , im Frühjahr 1975 für den MITS Altair 8800 entworfen und entwickelt . Die erste Version vom Juli 1975 unterstützte aufgrund der Kosten des 4-Kilobyte-Speichers des MITS Altair 8800 ein Format mit einfacher Genauigkeit (32 Bit) . Im Dezember 1975 fügte die 8-Kilobyte-Version ein Format mit doppelter Genauigkeit (64 Bit) hinzu. Ein Variantenformat mit einfacher Genauigkeit (40 Bit) wurde für andere CPUs übernommen, insbesondere für MOS 6502 ( Apple // , Commodore PET , Atari ), Motorola 6800 (MITS Altair 680) und Motorola 6809 ( TRS-80 Color Computer ). Alle Microsoft-Sprachprodukte von 1975 bis 1987 verwendeten das Microsoft Binary Format, bis Microsoft ab 1988 das IEEE-754-Standardformat in alle seine Produkte einführte, bis hin zu den aktuellen Versionen. MBF besteht aus dem MBF Single-Precision-Format (32 Bit, "6-digit BASIC"), dem MBF Extended-Precision-Format (40 Bit, "9-digit BASIC") und dem MBF Double-Precision-Format (64 Bit) ; jeder von ihnen wird mit einem 8-Bit-Exponenten dargestellt, gefolgt von einem Vorzeichenbit, gefolgt von einem Vorzeichen von 23, 31 bzw. 55 Bits.
  • Das Bfloat16-Format benötigt die gleiche Speicherkapazität (16 Bit) wie das IEEE 754-Format mit halber Genauigkeit, weist dem Exponenten jedoch 8 Bit statt 5 zu und bietet somit den gleichen Bereich wie eine IEEE 754- Zahl mit einfacher Genauigkeit . Der Kompromiss ist eine reduzierte Genauigkeit, da das nachfolgende Signifikand-Feld von 10 auf 7 Bit reduziert wird. Dieses Format wird hauptsächlich beim Training von Modellen für maschinelles Lernen verwendet, bei denen Reichweite wichtiger ist als Präzision. Viele Beschleuniger für maschinelles Lernen bieten Hardwareunterstützung für dieses Format.
  • Das TensorFloat-32-Format bietet das Beste der Bfloat16- und Halbpräzisionsformate mit 8 Bit Exponent als ersterem und 10 Bit nachgestelltem Signifikandenfeld als letzterem. Dieses Format wurde von Nvidia eingeführt , das in den Tensor-Cores seiner GPUs basierend auf der Nvidia Ampere-Architektur Hardware-Unterstützung dafür bereitstellt . Der Nachteil dieses Formats ist seine Gesamtgröße von 19 Bit, was keine Zweierpotenz ist. Laut Nvidia sollte dieses Format jedoch nur hardwareintern verwendet werden, um die Berechnungen zu beschleunigen, während Ein- und Ausgaben im 32-Bit-IEEE 754-Format mit einfacher Genauigkeit.
Bfloat16- und TensorFloat-32-Formatspezifikationen im Vergleich zu IEEE 754-Standardformaten mit halber Genauigkeit und einfacher Genauigkeit
Typ Unterschrift Exponent Nachgestelltes signifikantes Feld Gesamtbits
Halbe Präzision 1 5 10 16
Bfloat16 1 8 7 16
TensorFloat-32 1 8 10 19
Mit einfacher Genauigkeit 1 8 23 32

Darstellbare Zahlen, Umrechnung und Rundung

Alle im Gleitkommaformat ausgedrückten Zahlen sind ihrer Natur nach rationale Zahlen mit einer abschließenden Erweiterung in der entsprechenden Basis (z. B. einer abschließenden dezimalen Erweiterung zur Basis 10 oder einer abschließenden binären Erweiterung zur Basis 2). Irrationale Zahlen wie π oder √2 oder nicht abbreche rationale Zahlen müssen angenähert werden. Die Anzahl der Stellen (oder Bits) der Genauigkeit begrenzt auch die Menge der rationalen Zahlen, die genau dargestellt werden können. Zum Beispiel kann die Dezimalzahl 123456789 nicht exakt dargestellt werden, wenn nur acht Dezimalstellen Genauigkeit zur Verfügung stehen (sie würde auf einen der beiden übergreifend darstellbaren Werte gerundet, 12345678 × 10 1 oder 12345679 × 10 1 ), dasselbe gilt für Nicht- -terminating digits (. 5 werden aufgerundet auf entweder 0,55555555 0,55555556 oder).

Wenn eine Zahl in einem Format (wie einer Zeichenkette) dargestellt wird, das keine native Gleitkommadarstellung ist, die in einer Computerimplementierung unterstützt wird, dann ist eine Konvertierung erforderlich, bevor sie in dieser Implementierung verwendet werden kann. Wenn die Zahl im Gleitkommaformat exakt dargestellt werden kann, ist die Umrechnung exakt. Wenn es keine genaue Darstellung gibt, erfordert die Konvertierung eine Auswahl der Gleitkommazahl, die verwendet werden soll, um den ursprünglichen Wert darzustellen. Die gewählte Darstellung hat einen anderen Wert als das Original, und der so angepasste Wert wird als gerundeter Wert bezeichnet .

Ob eine rationale Zahl eine abschließende Entwicklung hat oder nicht, hängt von der Basis ab. Zum Beispiel hat in der Basis 10 die Zahl 1/2 eine abschließende Erweiterung (0.5), während die Zahl 1/3 nicht (0.333...) hat. In der Basis 2 terminieren nur rationale Zahlen mit Nennern, die Zweierpotenzen sind (wie 1/2 oder 3/16). Jedes rationale Element mit einem Nenner, der einen anderen Primfaktor als 2 hat, hat eine unendliche binäre Expansion. Das bedeutet, dass Zahlen, die im Dezimalformat kurz und genau erscheinen, bei der Umwandlung in binäre Gleitkommazahlen angenähert werden müssen. Zum Beispiel ist die Dezimalzahl 0.1 nicht in binären Gleitkommazahlen mit endlicher Genauigkeit darstellbar; die exakte binäre Darstellung hätte eine endlos fortgesetzte "1100"-Sequenz:

e = –4; s = 1100110011001100110011001100110011...,

wobei wie zuvor s der Signifikand und e der Exponent ist.

Auf 24 Bit gerundet wird dies zu

e = –4; s = 110011001100110011001101,

was tatsächlich 0,100000001490116119384765625 in Dezimalzahlen ist.

Als weiteres Beispiel ist die reelle Zahl π , binär dargestellt als unendliche Folge von Bits

11.0010010000111111011010101000100010000101101000110000100011010011...

aber ist

11.0010010000111111011011

wenn durch Runden auf eine Genauigkeit von 24 Bit angenähert .

In binären Gleitkommazahlen mit einfacher Genauigkeit wird dies als s  = 1,100100100000111111011011 mit e  = 1 dargestellt. Dies hat einen Dezimalwert von

3.141592 7410125732421875,

wohingegen eine genauere Annäherung an den wahren Wert von π ist

3.14159265358979323846264338327950 ...

Das Rundungsergebnis weicht vom wahren Wert um etwa 0,03 Teile pro Million ab und stimmt mit der dezimalen Darstellung von π in den ersten 7 Stellen überein. Die Differenz ist der Diskretisierungsfehler und wird durch das Maschinenepsilon begrenzt .

Die arithmetische Differenz zweier aufeinanderfolgender darstellbarer Gleitkommazahlen mit gleichem Exponenten wird als letzte Einheit (ULP) bezeichnet. Liegt beispielsweise keine darstellbare Zahl zwischen den darstellbaren Zahlen 1.45a70c22 hex und 1.45a70c24 hex , beträgt der ULP 2×16 –8 oder 2 –31 . Für Zahlen mit einem Exponententeil zur Basis 2 von 0, dh Zahlen mit einem Absolutwert größer oder gleich 1, aber kleiner als 2, ist ein ULP genau 2 −23 oder etwa 10 −7 in einfacher Genauigkeit und genau 2 −53 oder etwa 10 -16 in doppelter Genauigkeit. Das vorgeschriebene Verhalten von IEEE-konformer Hardware besteht darin, dass das Ergebnis innerhalb der Hälfte eines ULP liegt.

Rundungsmodi

Runden wird verwendet, wenn das genaue Ergebnis einer Gleitkommaoperation (oder einer Konvertierung in das Gleitkommaformat) mehr Ziffern benötigen würde, als der Signifikand Ziffern enthält. IEEE 754 erfordert eine korrekte Rundung : Das heißt, das gerundete Ergebnis ist, als ob eine unendlich genaue Arithmetik verwendet wurde, um den Wert zu berechnen und dann zu runden (obwohl in der Implementierung nur drei zusätzliche Bits benötigt werden, um dies sicherzustellen). Es gibt verschiedene Rundungsschemata (oder Rundungsmodi ). Historisch gesehen war das Abschneiden der typische Ansatz. Seit der Einführung von IEEE 754 wird die Standardmethode ( Runde zum nächsten, Bindungen zu gerade , manchmal auch Banker's Rounding genannt) häufiger verwendet. Dieses Verfahren rundet das ideale (unendlich genaue) Ergebnis einer arithmetischen Operation auf den nächsten darstellbaren Wert und gibt diese Darstellung als Ergebnis aus. Bei Gleichstand wird der Wert gewählt, bei dem der Signifikand in eine gerade Ziffer enden würde. Der IEEE 754-Standard erfordert, dass auf alle grundlegenden algebraischen Operationen, einschließlich Quadratwurzel und Konvertierungen, dieselbe Rundung angewendet wird, wenn ein numerisches (Nicht-NaN-)Ergebnis vorliegt. Dies bedeutet, dass die Ergebnisse von IEEE 754-Operationen in allen Bits des Ergebnisses vollständig bestimmt sind, mit Ausnahme der Darstellung von NaNs. ("Library"-Funktionen wie Cosinus und Log sind nicht vorgeschrieben.)

Alternative Rundungsoptionen sind ebenfalls verfügbar. IEEE 754 spezifiziert die folgenden Rundungsmodi:

  • Auf die nächste Runde aufrunden, wobei auf die nächste gerade Ziffer an der gewünschten Position gerundet wird (der Standard und bei weitem der gebräuchlichste Modus)
  • auf nächste Runde runden, wobei von Null weg gerundet wird (optional für binäre Gleitkommazahlen und häufig in Dezimalzahlen verwendet)
  • aufrunden (in Richtung +∞; negative Ergebnisse also auf Null aufrunden)
  • abrunden (in Richtung −∞; negative Ergebnisse also von Null weg runden)
  • auf Null runden (Abschneiden; es ähnelt dem üblichen Verhalten von Float-to-Integer-Konvertierungen, die -3,9 in -3 und 3,9 in 3 konvertieren)

Alternative Modi sind nützlich, wenn der eingeführte Fehlerbetrag begrenzt werden muss. Anwendungen, die einen begrenzten Fehler erfordern, sind Gleitkomma- und Intervallarithmetik mit mehreren Genauigkeiten . Die alternativen Rundungsmodi sind auch bei der Diagnose numerischer Instabilität nützlich: Wenn die Ergebnisse eines Unterprogramms zwischen Runden auf + und − unendlich variieren, ist es wahrscheinlich numerisch instabil und von Rundungsfehlern betroffen.

Binär-zu-Dezimal-Umwandlung mit minimaler Anzahl von Stellen

Die Umwandlung einer binären Gleitkommazahl mit doppelter Genauigkeit in eine Dezimalzeichenfolge ist eine gängige Operation, aber ein Algorithmus, der sowohl genaue als auch minimale Ergebnisse liefert, erschien erst 1990 mit Steele und Whites Dragon4. Einige der Verbesserungen seither umfassen:

  • dtoa.c von David M. Gay , eine praktische Open-Source-Implementierung vieler Ideen in Dragon4.
  • Grisu3, mit einer 4-fachen Beschleunigung, da die Verwendung von Bignums entfällt . Muss mit einem Fallback verwendet werden, da es in ~0,5 % der Fälle fehlschlägt.
  • Errol3, ein immer erfolgreicher Algorithmus, ähnlich wie Grisu3, aber langsamer als dieser. Offenbar nicht so gut wie ein früh ausscheidender Grisu mit Fallback.
  • Ryū, ein immer erfolgreicher Algorithmus, der schneller und einfacher ist als Grisu3.

Viele moderne Sprachlaufzeiten verwenden Grisu3 mit einem Dragon4-Fallback.

Dezimal-zu-Binär-Konvertierung

Das Problem des Parsens einer Dezimalzeichenfolge in eine binäre FP-Darstellung ist komplex, wobei ein genauer Parser erst in Clingers Arbeit von 1990 (implementiert in dtoa.c) auftaucht. Weitere Arbeiten sind ebenfalls in Richtung schnelleres Parsing fortgeschritten.

Gleitkomma-Rechenoperationen

Zur Vereinfachung der Darstellung und des Verständnisses wird in den Beispielen ein dezimales Radix mit 7-stelliger Genauigkeit verwendet, wie im IEEE 754- Dezimal32- Format. Die Grundprinzipien sind bei allen Radixen oder Genauigkeiten gleich, außer dass die Normalisierung optional ist (sie hat keinen Einfluss auf den numerischen Wert des Ergebnisses). Dabei bezeichnet s den Signifikanden und e den Exponenten.

Addition und Subtraktion

Eine einfache Methode zum Hinzufügen von Gleitkommazahlen besteht darin, sie zunächst mit demselben Exponenten darzustellen. Im folgenden Beispiel wird die zweite Zahl um drei Stellen nach rechts verschoben, und man fährt dann mit der üblichen Additionsmethode fort:

  123456.7 = 1.234567 × 10^5
  101.7654 = 1.017654 × 10^2 = 0.001017654 × 10^5
  Hence:
  123456.7 + 101.7654 = (1.234567 × 10^5) + (1.017654 × 10^2)
                      = (1.234567 × 10^5) + (0.001017654 × 10^5)
                      = (1.234567 + 0.001017654) × 10^5
                      =  1.235584654 × 10^5

Im Detail:

  e=5;  s=1.234567     (123456.7)
+ e=2;  s=1.017654     (101.7654)
  e=5;  s=1.234567
+ e=5;  s=0.001017654  (after shifting)
--------------------
  e=5;  s=1.235584654  (true sum: 123558.4654)

Dies ist das wahre Ergebnis, die genaue Summe der Operanden. Sie wird auf sieben Stellen gerundet und ggf. normalisiert. Das Endergebnis ist

  e=5;  s=1.235585    (final sum: 123558.5)

Die niedrigsten drei Ziffern des zweiten Operanden (654) gehen im Wesentlichen verloren. Dies ist ein Rundungsfehler . In extremen Fällen kann die Summe zweier von Null verschiedenen Zahlen gleich einer von ihnen sein:

  e=5;  s=1.234567
+ e=−3; s=9.876543
  e=5;  s=1.234567
+ e=5;  s=0.00000009876543 (after shifting)
----------------------
  e=5;  s=1.23456709876543 (true sum)
  e=5;  s=1.234567         (after rounding and normalization)

In den obigen konzeptionellen Beispielen scheint es, dass eine große Anzahl zusätzlicher Ziffern vom Addierer bereitgestellt werden müsste, um eine korrekte Rundung sicherzustellen; jedoch müssen für binäre Addition oder Subtraktion unter Verwendung sorgfältiger Implementierungstechniken nur ein Schutzbit , ein Rundungsbit und ein zusätzliches Sticky- Bit über die Genauigkeit der Operanden hinaus übertragen werden.

Ein weiteres Problem des Signifikanzverlustes tritt auf, wenn Annäherungen an zwei nahezu gleiche Zahlen subtrahiert werden. Im folgenden Beispiel e  = 5; s  = 1,234571 und e  = 5; s  = 1,234567 sind Annäherungen an die rationalen Zahlen 123457,1467 und 123456.659.

  e=5;  s=1.234571
− e=5;  s=1.234567
----------------
  e=5;  s=0.000004
  e=−1; s=4.000000 (after rounding and normalization)

Die Gleitkommadifferenz wird genau berechnet, weil die Zahlen nahe beieinander liegen – das Lemma von Sterbenz garantiert dies auch bei Unterlauf, wenn ein allmählicher Unterlauf unterstützt wird. Trotzdem beträgt die Differenz der ursprünglichen Zahlen e  = −1; s  = 4.877000, was mehr als 20 % von der Differenz e  = –1 abweicht ; s  = 4.000000 der Näherungen. Im Extremfall können alle signifikanten Stellen der Genauigkeit verloren gehen. Diese Aufhebung veranschaulicht die Gefahr, wenn man davon ausgeht, dass alle Ziffern eines berechneten Ergebnisses sinnvoll sind. Der Umgang mit den Folgen dieser Fehler ist ein Thema der numerischen Analysis ; siehe auch Genauigkeitsprobleme .

Multiplikation und Division

Zum Multiplizieren werden die Signifikanten multipliziert, während die Exponenten addiert werden, und das Ergebnis wird gerundet und normalisiert.

  e=3;  s=4.734612
× e=5;  s=5.417242
-----------------------
  e=8;  s=25.648538980104 (true product)
  e=8;  s=25.64854        (after rounding)
  e=9;  s=2.564854        (after normalization)

Auf ähnliche Weise wird die Division durch Subtrahieren des Exponenten des Divisors vom Exponenten des Dividenden und Dividieren des Signifikanden des Dividenden durch den Signifikand des Divisors durchgeführt.

Es gibt keine Aufhebungs- oder Absorptionsprobleme bei der Multiplikation oder Division, obwohl sich kleine Fehler ansammeln können, wenn Operationen nacheinander ausgeführt werden. In der Praxis kann die Art und Weise, wie diese Operationen in digitaler Logik ausgeführt werden, ziemlich komplex sein (siehe Booths Multiplikationsalgorithmus und Divisionsalgorithmus ). Eine schnelle und einfache Methode finden Sie in der Horner-Methode .

Umgang mit Ausnahmefällen

Bei der Gleitkommaberechnung in einem Computer können drei Arten von Problemen auftreten:

  • Eine Operation kann mathematisch undefiniert sein, wie z. B. ∞/∞ oder Division durch Null .
  • Eine Operation kann im Prinzip zulässig sein, aber durch das spezielle Format nicht unterstützt werden, zum Beispiel die Berechnung der Quadratwurzel von −1 oder des inversen Sinus von 2 (beide ergeben komplexe Zahlen ).
  • Eine Operation kann im Prinzip zulässig sein, aber das Ergebnis kann nicht im angegebenen Format dargestellt werden, weil der Exponent zu groß oder zu klein ist, um in das Exponentenfeld zu kodieren. Ein solches Ereignis wird als Überlauf (Exponent zu groß), Unterlauf (Exponent zu klein) oder Denormalisierung (Präzisionsverlust) bezeichnet.

Vor dem IEEE-Standard führten solche Bedingungen normalerweise zum Beenden des Programms oder lösten eine Art Falle aus , die der Programmierer abfangen könnte. Wie dies funktionierte, war systemabhängig, dh Gleitkommaprogramme waren nicht portabel . (Der Begriff "Ausnahme", wie er in IEEE 754 verwendet wird, ist ein allgemeiner Begriff, der eine außergewöhnliche Bedingung bedeutet, die nicht unbedingt ein Fehler ist, und ist eine andere Verwendung als die, die normalerweise in Programmiersprachen wie C++ oder Java definiert ist, in denen ein " Ausnahme " ist ein alternativer Kontrollfluss, der näher an dem liegt, was in der IEEE 754-Terminologie als "Falle" bezeichnet wird.)

Hier wird das erforderliche Standardverfahren zum Behandeln von Ausnahmen gemäß IEEE 754 erörtert (das optionale Einfangen von IEEE 754 und andere Modi der "alternativen Ausnahmebehandlung" werden nicht erörtert). Arithmetische Ausnahmen müssen (standardmäßig) in "Sticky"-Status-Flag-Bits aufgezeichnet werden. Dass sie "klebrig" sind, bedeutet, dass sie bei der nächsten (arithmetischen) Operation nicht zurückgesetzt werden, sondern bis zum expliziten Zurücksetzen gesetzt bleiben. Die Verwendung von "sticky"-Flags ermöglicht es daher, das Testen von Ausnahmebedingungen bis nach einem vollständigen Gleitkomma-Ausdruck oder einer vollständigen Subroutine zu verzögern: Ohne sie würden Ausnahmebedingungen, die sonst nicht ignoriert werden könnten, ein explizites Testen unmittelbar nach jeder Gleitkomma-Operation erfordern. Standardmäßig gibt eine Operation immer ein Ergebnis gemäß der Spezifikation zurück, ohne die Berechnung zu unterbrechen. Zum Beispiel gibt 1/0 +∞ zurück, während gleichzeitig das Division-durch-Null-Flag-Bit gesetzt wird (diese Vorgabe von ∞ ist so konzipiert, dass sie bei Verwendung in nachfolgenden Operationen oft ein endliches Ergebnis zurückgibt und daher sicher ignoriert wird).

Der ursprüngliche IEEE 754-Standard versäumte es jedoch, Operationen zu empfehlen, um solche Sätze von arithmetischen Ausnahmeflag-Bits zu handhaben. Während diese also in Hardware implementiert wurden, boten anfangs Programmiersprachenimplementierungen normalerweise keine Möglichkeit, auf sie zuzugreifen (abgesehen von Assembler). Im Laufe der Zeit wurden einige Programmiersprachenstandards (zB C99 /C11 und Fortran) aktualisiert, um Methoden für den Zugriff und die Änderung von Status-Flag-Bits anzugeben. Die Version 2008 des IEEE 754-Standards spezifiziert nun einige Operationen für den Zugriff und die Handhabung der arithmetischen Flag-Bits. Das Programmiermodell basiert auf einem einzelnen Ausführungs-Thread und dessen Verwendung durch mehrere Threads muss mit Mitteln außerhalb des Standards gehandhabt werden (zB C11 gibt an, dass die Flags einen Thread-lokalen Speicher haben ).

IEEE 754 spezifiziert fünf arithmetische Ausnahmen, die in den Status-Flags ("Sticky Bits") aufzuzeichnen sind:

  • inexact , wird gesetzt, wenn der gerundete (und zurückgegebene) Wert vom mathematisch exakten Ergebnis der Operation abweicht.
  • underflow , wird gesetzt, wenn der gerundete Wert winzig ist (wie in IEEE 754) und ungenau (oder möglicherweise beschränkt auf Denormalisierungsverluste, wie in der 1984er Version von IEEE 754), und gibt einen subnormalen Wert einschließlich der Nullen zurück.
  • overflow , wird gesetzt, wenn der Absolutwert des gerundeten Werts zu groß für die Darstellung ist. Es wird ein unendlicher oder maximaler endlicher Wert zurückgegeben, je nachdem, welche Rundung verwendet wird.
  • Division durch Null , wird gesetzt, wenn das Ergebnis bei gegebenen endlichen Operanden unendlich ist, und gibt eine Unendlichkeit zurück, entweder +∞ oder −∞.
  • ungültig , wird gesetzt, wenn ein reellwertiges Ergebnis nicht zurückgegeben werden kann, zB sqrt(−1) oder 0/0, was ein ruhiges NaN zurückgibt.
Abb. 1: Widerstände parallel, mit Gesamtwiderstand

Der Standardrückgabewert für jede der Ausnahmen soll in den meisten Fällen das richtige Ergebnis liefern, sodass die Ausnahmen in den meisten Codes ignoriert werden können. inexact gibt ein korrekt gerundetes Ergebnis zurück und underflow gibt einen denormalisierten kleinen Wert zurück und kann daher fast immer ignoriert werden. Divide-by-Zero gibt genau unendlich zurück, was dann typischerweise eine endliche Zahl teilt und so Null ergibt, oder ansonsten anschließend eine ungültige Ausnahme ausgibt, wenn nicht, und kann daher auch normalerweise ignoriert werden. Beispielsweise ist der effektive Widerstand von n parallel geschalteten Widerständen (siehe Abb. 1) gegeben durch . Wenn sich ein Kurzschluss entwickelt , während auf 0 gesetzt ist, wird +unendlich zurückgegeben, was wie erwartet ein Endergebnis von 0 ergibt (siehe das Beispiel für Kettenbruch der IEEE 754-Design-Grundlage für ein weiteres Beispiel).

Überlauf- und ungültige Ausnahmen können normalerweise nicht ignoriert werden, stellen jedoch nicht unbedingt Fehler dar: Zum Beispiel kann eine Routine zum Auffinden von Roots als Teil ihres normalen Betriebs eine übergebene Funktion bei Werten außerhalb ihrer Domäne auswerten und NaN und . zurückgeben ein ungültiges Ausnahmeflag, das ignoriert werden soll, bis ein brauchbarer Startpunkt gefunden wird.

Genauigkeitsprobleme

Die Tatsache, dass Gleitkommazahlen nicht alle reellen Zahlen genau darstellen können und dass Gleitkommaoperationen echte arithmetische Operationen nicht genau darstellen können, führt zu vielen überraschenden Situationen. Dies hängt mit der endlichen Genauigkeit zusammen, mit der Computer im Allgemeinen Zahlen darstellen.

Zum Beispiel bedeutet die Nichtdarstellbarkeit von 0,1 und 0,01 (in binärer Form), dass das Ergebnis des Versuchs, 0,1 zu quadrieren, weder 0,01 noch die darstellbare Zahl ist, die ihr am nächsten kommt. In der 24-Bit-Darstellung (einfache Genauigkeit) wurde 0,1 (dezimal) zuvor als e  = -4 angegeben ; s  = 110011001100110011001101 , das ist

0,100000001490116119384765625 genau.

Das Quadrieren dieser Zahl ergibt

0,010000000298023226097399174250313080847263336181640625 genau.

Das Quadrieren mit Gleitkomma-Hardware mit einfacher Genauigkeit (mit Rundung) ergibt

0,010000000707805156707763671875 genau.

Aber die darstellbare Zahl, die 0,01 am nächsten kommt, ist

0,009999999776482582092285156250 genau.

Außerdem bedeutet die Nichtdarstellbarkeit von π (und π/2), dass eine versuchte Berechnung von tan(π/2) weder ein Ergebnis von Unendlich ergibt, noch wird es in den üblichen Gleitkommaformaten (vorausgesetzt, ein genaues Umsetzung von Bräune). Es ist für Standard-Gleitkomma-Hardware einfach nicht möglich zu versuchen, tan(π/2) zu berechnen, da π/2 nicht exakt dargestellt werden kann. Diese Berechnung in C:

/* Enough digits to be sure we get the correct approximation. */
double pi = 3.1415926535897932384626433832795;
double z = tan(pi/2.0);

ergibt das Ergebnis 16331239353195370.0. Bei einfacher Genauigkeit (mit der tanfFunktion) lautet das Ergebnis −22877332.0.

Ebenso führt eine versuchte Berechnung von sin(π) nicht zu Null. Das Ergebnis ist (ungefähr) 0,1225 × 10 –15 mit doppelter Genauigkeit oder –0,8742 × 10 –7 mit einfacher Genauigkeit.

Während Gleitkomma-Addition und -Multiplikation beide kommutativ sind ( a + b = b + a und a × b = b × a ), sind sie nicht unbedingt assoziativ . Das heißt, ( a + b ) + c ist nicht notwendigerweise gleich a + ( b + c ) . Mit 7-stelliger Vorzeichen- und Dezimalarithmetik:

 a = 1234.567, b = 45.67834, c = 0.0004
 (a + b) + c:
     1234.567   (a)
   +   45.67834 (b)
   ____________
     1280.24534   rounds to   1280.245
    1280.245  (a + b)
   +   0.0004 (c)
   ____________
    1280.2454   rounds to   1280.245  ← (a + b) + c
 a + (b + c):
   45.67834 (b)
 +  0.0004  (c)
 ____________
   45.67874
   1234.567   (a)
 +   45.67874   (b + c)
 ____________
   1280.24574   rounds to   1280.246 ← a + (b + c)

Sie sind auch nicht unbedingt distributiv . Das heißt, ( a + b ) × c muss nicht gleich a × c + b × c sein :

 1234.567 × 3.333333 = 4115.223
 1.234567 × 3.333333 = 4.115223
                       4115.223 + 4.115223 = 4119.338
 but
 1234.567 + 1.234567 = 1235.802
                       1235.802 × 3.333333 = 4119.340

Neben Signifikanzverlust, Unfähigkeit, Zahlen wie und 0,1 exakt darzustellen, und anderen leichten Ungenauigkeiten können folgende Phänomene auftreten:

  • Aufhebung : Die Subtraktion von nahezu gleichen Operanden kann einen extremen Genauigkeitsverlust verursachen. Wenn wir zwei fast gleiche Zahlen subtrahieren, setzen wir die höchstwertigen Stellen auf Null und lassen uns nur die unbedeutenden und fehlerhaften Stellen. Bei der Bestimmung einer Ableitung einer Funktion wird beispielsweise die folgende Formel verwendet:

    Intuitiv würde man ein h sehr nahe bei Null haben wollen; Bei der Verwendung von Gleitkommaoperationen ergibt die kleinste Zahl jedoch nicht die beste Näherung einer Ableitung. Wenn h kleiner wird, wird die Differenz zwischen f ( a + h ) und f ( a ) kleiner, wodurch die höchstwertigen und die am wenigsten fehlerhaften Ziffern ausgelöscht werden und die fehlerhaftesten Stellen wichtiger werden. Als Ergebnis ergibt die kleinstmögliche Zahl von h eine fehlerhaftere Näherung einer Ableitung als eine etwas größere Zahl. Dies ist vielleicht das häufigste und schwerwiegendste Genauigkeitsproblem.
  • Konvertierungen in Integer sind nicht intuitiv: Die Konvertierung von (63.0/9.0) in Integer ergibt 7, aber die Konvertierung (0.63/0.09) kann 6 ergeben. Dies liegt daran, dass Konvertierungen im Allgemeinen eher abgeschnitten als gerundet werden. Boden- und Deckenfunktionen können Antworten liefern, die um eins vom intuitiv erwarteten Wert abweichen.
  • Begrenzter Exponentenbereich: Ergebnisse können überlaufen und unendlich ergeben, oder unterlaufen, was zu einer subnormalen Zahl oder Null führt. In diesen Fällen geht die Präzision verloren.
  • Das Testen auf sichere Division ist problematisch: Die Überprüfung, ob der Divisor nicht Null ist, garantiert nicht, dass eine Division nicht überläuft.
  • Die Prüfung auf Gleichberechtigung ist problematisch. Zwei mathematisch gleiche Rechenfolgen können durchaus unterschiedliche Gleitkommawerte erzeugen.

Vorfälle

Maschinenpräzision und Rückwärtsfehleranalyse

Die Maschinengenauigkeit ist eine Größe, die die Genauigkeit eines Gleitkommasystems charakterisiert und bei der Rückwärtsfehleranalyse von Gleitkommaalgorithmen verwendet wird. Es wird auch als Einheitsrundung oder Maschinenepsilon bezeichnet . Normalerweise als Ε mach bezeichnet , hängt sein Wert von der speziellen verwendeten Rundung ab.

Mit Rundung auf Null,

in der Erwägung, dass das Runden auf das nächste,

Dies ist wichtig, da es den relativen Fehler bei der Darstellung einer beliebigen reellen Zahl x ungleich null innerhalb des normalisierten Bereichs eines Gleitkommasystems begrenzt:

Die Rückwärtsfehleranalyse, deren Theorie von James H. Wilkinson entwickelt und populär gemacht wurde , kann verwendet werden, um festzustellen, dass ein Algorithmus, der eine numerische Funktion implementiert, numerisch stabil ist. Der grundlegende Ansatz besteht darin, zu zeigen, dass das berechnete Ergebnis zwar aufgrund von Rundungsfehlern nicht genau richtig ist, aber die genaue Lösung für ein naheliegendes Problem mit leicht gestörten Eingabedaten ist. Wenn die erforderliche Störung klein ist, in der Größenordnung der Unsicherheit in den Eingabedaten, dann sind die Ergebnisse in gewisser Weise so genau, wie es die Daten "verdienen". Der Algorithmus wird dann als rückwärts stabil definiert . Stabilität ist ein Maß für die Empfindlichkeit gegenüber Rundungsfehlern eines gegebenen numerischen Verfahrens; Im Gegensatz dazu zeigt die Bedingungszahl einer Funktion für ein gegebenes Problem die inhärente Empfindlichkeit der Funktion gegenüber kleinen Störungen in ihrer Eingabe an und ist unabhängig von der zur Lösung des Problems verwendeten Implementierung.

Betrachten Sie als triviales Beispiel einen einfachen Ausdruck, der das innere Produkt von (Länge zwei) Vektoren und , dann

und so

wo

wo

per Definition ist dies die Summe von zwei leicht gestörten (in der Größenordnung von Ε mach ) Eingabedaten und ist somit rückwärtsstabil. Für realistischere Beispiele in der numerischen linearen Algebra siehe Higham 2002 und andere Referenzen unten.

Minimierung der Auswirkungen von Genauigkeitsproblemen

Obwohl, wie bereits erwähnt, einzelne arithmetische Operationen von IEEE 754 mit einer Genauigkeit von bis zu einem halben ULP garantiert sind, können kompliziertere Formeln aufgrund von Rundung an größeren Fehlern leiden. Der Genauigkeitsverlust kann erheblich sein, wenn ein Problem oder seine Daten schlecht konditioniert sind , was bedeutet, dass das korrekte Ergebnis gegenüber winzigen Störungen in seinen Daten überempfindlich ist. Aber selbst gut konditionierte Funktionen können einen großen Genauigkeitsverlust erleiden, wenn ein für diese Daten numerisch instabiler Algorithmus verwendet wird: Scheinbar äquivalente Formulierungen von Ausdrücken in einer Programmiersprache können sich in ihrer numerischen Stabilität deutlich unterscheiden. Ein Ansatz, um das Risiko eines solchen Genauigkeitsverlusts zu beseitigen, ist der Entwurf und die Analyse numerisch stabiler Algorithmen, was ein Ziel des als numerischer Analysis bekannten Teilgebiets der Mathematik ist . Ein weiterer Ansatz, der gegen das Risiko numerischer Instabilitäten schützen kann, ist die Berechnung von Zwischenwerten (Scratch) in einem Algorithmus mit einer höheren Genauigkeit als das Endergebnis erfordert, wodurch ein solches Risiko beseitigt oder um Größenordnungen reduziert werden kann: IEEE 754 Quadruple Precision und Extended Precision sind für diesen Zweck beim Rechnen mit doppelter Genauigkeit ausgelegt.

Zum Beispiel ist der folgende Algorithmus eine direkte Implementierung, um die Funktion A ( x ) = ( x −1) / (exp( x −1) − 1) zu berechnen, die bei 1.0 gut konditioniert ist, jedoch als numerisch instabil und verlieren bis zur Hälfte der signifikanten Stellen, die von der Arithmetik getragen werden, wenn sie nahe 1,0 berechnet wird.

double A(double X)
{
        double Y, Z;  // [1]
        Y = X - 1.0;
        Z = exp(Y);
        if (Z != 1.0)
                Z = Y / (Z - 1.0); // [2]
        return Z;
}

Werden jedoch Zwischenrechnungen alle in erweiterter Genauigkeit durchgeführt (zB durch Setzen von Zeile [1] auf C99 long double ), dann kann bis zur vollen Genauigkeit im endgültigen Doppelergebnis festgehalten werden. Alternativ zeigt eine numerische Analyse des Algorithmus, dass die folgende nicht offensichtliche Änderung an Zeile [2] vorgenommen wird:

Z = log(Z) / (Z - 1.0);

dann wird der Algorithmus numerisch stabil und kann mit voller doppelter Genauigkeit rechnen.

Um die Eigenschaften solch sorgfältig konstruierter numerisch stabiler Programme beizubehalten, ist eine sorgfältige Handhabung durch den Compiler erforderlich. Bestimmte "Optimierungen", die Compiler vornehmen können (z. B. Neuordnungsvorgänge) können den Zielen einer gut funktionierenden Software zuwiderlaufen. Es gibt einige Kontroversen über die Fehler von Compilern und Sprachdesigns in diesem Bereich: C99 ist ein Beispiel für eine Sprache, in der solche Optimierungen sorgfältig spezifiziert werden, um die numerische Genauigkeit zu erhalten. Siehe die externen Referenzen am Ende dieses Artikels.

Eine detaillierte Behandlung der Techniken zum Schreiben hochwertiger Gleitkomma-Software würde den Rahmen dieses Artikels sprengen, und es wird auf den Leser und die anderen Referenzen am Ende dieses Artikels verwiesen. Kahan schlägt mehrere Faustregeln vor, die das Risiko numerischer Anomalien zusätzlich oder anstelle einer sorgfältigeren numerischen Analyse um Größenordnungen verringern können. Dazu gehören: wie oben erwähnt das Berechnen aller Ausdrücke und Zwischenergebnisse mit der höchsten von der Hardware unterstützten Genauigkeit (eine allgemeine Faustregel ist, die doppelte Genauigkeit des gewünschten Ergebnisses zu tragen, dh mit doppelter Genauigkeit für ein Endergebnis mit einfacher Genauigkeit zu berechnen, oder in doppelter erweiterter oder vierfacher Genauigkeit für Ergebnisse mit bis zu doppelter Genauigkeit); und Runden von Eingabedaten und Ergebnissen nur auf die erforderliche und von den Eingabedaten unterstützte Genauigkeit (das Tragen einer übermäßigen Genauigkeit im Endergebnis über die erforderliche und von den Eingabedaten unterstützte Genauigkeit kann irreführend sein, erhöht die Speicherkosten und verringert die Geschwindigkeit, und die überschüssigen Bits können die Konvergenz numerischer Verfahren beeinflussen: insbesondere konvergiert die erste Form des unten angegebenen iterativen Beispiels korrekt, wenn diese Faustregel verwendet wird). Es folgen kurze Beschreibungen einiger zusätzlicher Probleme und Techniken.

Da Dezimalbrüche oft nicht exakt in binären Gleitkommazahlen dargestellt werden können, ist eine solche Arithmetik am besten, wenn sie einfach dazu verwendet wird, reale Größen über einen weiten Skalenbereich zu messen (wie die Umlaufzeit eines Mondes um Saturn oder die Masse eines Protons ) und im schlimmsten Fall, wenn erwartet wird, dass die Wechselwirkungen von Größen, ausgedrückt als Dezimalketten, von denen erwartet wird, dass sie exakt sind, modelliert werden. Ein Beispiel für letzteren Fall sind finanzielle Berechnungen. Aus diesem Grund verwendet Finanzsoftware in der Regel keine binäre Gleitkommazahlendarstellung. Der Datentyp "dezimal" der Programmiersprachen C# und Python sowie die dezimalen Formate des Standards IEEE 754-2008 sollen die Probleme binärer Gleitkommadarstellungen vermeiden, wenn sie auf von Menschen eingegebene exakte Dezimalwerte angewendet werden die Arithmetik verhält sich immer wie erwartet, wenn Zahlen dezimal gedruckt werden.

Die Erwartungen an die Mathematik können im Bereich der Gleitkommaberechnung möglicherweise nicht erfüllt werden. Zum Beispiel ist bekannt, dass , und dass , jedoch kann man sich nicht auf diese Tatsachen verlassen, wenn die beteiligten Größen das Ergebnis einer Gleitkommaberechnung sind.

Die Verwendung des Gleichheitstests ( if (x==y) ...) erfordert Sorgfalt im Umgang mit Gleitkommazahlen. Selbst einfache Ausdrücke wie 0.6/0.2-3==0werden auf den meisten Computern nicht wahr sein (in IEEE 754 ist die doppelte Genauigkeit beispielsweise 0.6/0.2 - 3ungefähr gleich -4.44089209850063e-16). Folglich werden solche Tests manchmal durch "unscharfe" Vergleiche ersetzt ( if (abs(x-y) < epsilon) ..., wobei Epsilon ausreichend klein und auf die Anwendung zugeschnitten ist, z. B. 1.0E−13). Die Weisheit, dies zu tun, ist sehr unterschiedlich und kann eine numerische Analyse erfordern, um Epsilon zu begrenzen. Aus der Primärdatendarstellung abgeleitete Werte und deren Vergleiche sollten mit einer breiteren, erweiterten Genauigkeit durchgeführt werden, um das Risiko solcher Inkonsistenzen aufgrund von Rundungsfehlern zu minimieren. Oft ist es besser, den Code so zu organisieren, dass solche Tests unnötig sind. Beispielsweise können in der Computergeometrie mit adaptiven Präzisions- oder exakten arithmetischen Verfahren genaue Tests durchgeführt werden, ob ein Punkt abseits oder auf einer durch andere Punkte definierten Linie oder Ebene liegt.

Kleine Fehler in der Gleitkomma-Arithmetik können zunehmen, wenn mathematische Algorithmen Operationen enorm oft ausführen. Einige Beispiele sind Matrixinversion , Eigenvektorberechnung und das Lösen von Differentialgleichungen. Diese Algorithmen müssen mit numerischen Ansätzen wie der iterativen Verfeinerung sehr sorgfältig entworfen werden , wenn sie gut funktionieren sollen.

Die Summation eines Vektors von Gleitkommawerten ist ein grundlegender Algorithmus im wissenschaftlichen Rechnen , und daher ist es wichtig, sich darüber im Klaren zu sein , wann ein Signifikanzverlust auftreten kann. Addiert man beispielsweise sehr viele Zahlen, so sind die einzelnen Summanden im Vergleich zur Summe sehr klein. Dies kann zu einem Bedeutungsverlust führen. Eine typische Ergänzung wäre dann so etwas wie

3253.671
+  3.141276
-----------
3256.812

Die unteren 3 Stellen der Addenden gehen effektiv verloren. Nehmen wir zum Beispiel an, dass man viele Zahlen addieren muss, die alle ungefähr gleich 3 sind. Nachdem 1000 von ihnen addiert wurden, beträgt die laufende Summe ungefähr 3000; die verlorenen Ziffern werden nicht wiederhergestellt. Der Kahan-Summationsalgorithmus kann verwendet werden, um die Fehler zu reduzieren.

Rundungsfehler können die Konvergenz und Genauigkeit iterativer numerischer Verfahren beeinträchtigen. Als Beispiel hat Archimedes π angenähert, indem er die Umfänge von Polygonen berechnete, die einen Kreis beschreiben und umschreiben, beginnend mit Sechsecken und sukzessive die Anzahl der Seiten verdoppelt. Wie oben erwähnt, können Berechnungen auf eine Weise neu angeordnet werden, die mathematisch äquivalent, aber weniger fehleranfällig ist ( numerische Analyse ). Zwei Formen der Rekursionsformel für das umschriebene Polygon sind:

  • Erstes Formular:
  • zweite Form:
  • , konvergierend als

Hier ist eine Berechnung mit IEEE "double" (ein Signifikant mit 53 Bit Genauigkeit) Arithmetik:

 i   6 × 2i × ti, first form    6 × 2i × ti, second form
---------------------------------------------------------
 0   3.4641016151377543863      3.4641016151377543863
 1   3.2153903091734710173      3.2153903091734723496
 2   3.1596599420974940120      3.1596599420975006733
 3   3.1460862151314012979      3.1460862151314352708
 4   3.1427145996453136334      3.1427145996453689225
 5   3.1418730499801259536      3.1418730499798241950
 6   3.1416627470548084133      3.1416627470568494473
 7   3.1416101765997805905      3.1416101766046906629
 8   3.1415970343230776862      3.1415970343215275928
 9   3.1415937488171150615      3.1415937487713536668
10   3.1415929278733740748      3.1415929273850979885
11   3.1415927256228504127      3.1415927220386148377
12   3.1415926717412858693      3.1415926707019992125
13   3.1415926189011456060      3.1415926578678454728
14   3.1415926717412858693      3.1415926546593073709
15   3.1415919358822321783      3.1415926538571730119
16   3.1415926717412858693      3.1415926536566394222
17   3.1415810075796233302      3.1415926536065061913
18   3.1415926717412858693      3.1415926535939728836
19   3.1414061547378810956      3.1415926535908393901
20   3.1405434924008406305      3.1415926535900560168
21   3.1400068646912273617      3.1415926535898608396
22   3.1349453756585929919      3.1415926535898122118
23   3.1400068646912273617      3.1415926535897995552
24   3.2245152435345525443      3.1415926535897968907
25                              3.1415926535897962246
26                              3.1415926535897962246
27                              3.1415926535897962246
28                              3.1415926535897962246
              The true value is 3.14159265358979323846264338327...

Während die beiden Formen der Rekursionsformel mathematisch eindeutig äquivalent sind, subtrahiert die erste 1 von einer Zahl, die sehr nahe bei 1 liegt, was zu einem zunehmend problematischen Verlust signifikanter Stellen führt . Da die Wiederholung wiederholt angewendet wird, verbessert sich die Genauigkeit zunächst, verschlechtert sich dann jedoch. Es wird nie besser als etwa 8 Stellen, obwohl 53-Bit-Arithmetik eine Genauigkeit von etwa 16 Stellen erreichen sollte. Wenn die zweite Form der Wiederholung verwendet wird, konvergiert der Wert auf eine Genauigkeit von 15 Stellen.

"Schnelle Mathematik" Optimierung

Der zuvor erwähnte Mangel an Assoziativität von Gleitkommaoperationen im allgemeinen bedeutet , dass Compiler nicht als effektiv Neuordnungs arithmetischer Ausdrücke , wie sie konnten mit ganzzahligen und Festkomma - Arithmetik, eine Straßensperre in Optimierungen wie präsentierenden gemeinsame Teilausdrücke Eliminierung und auto- Vektorisierung . Die Option "schnelle Mathematik" bei vielen Compilern (ICC, GCC, Clang, MSVC...) aktiviert die Reassoziation zusammen mit unsicheren Annahmen wie dem Fehlen von NaN und unendlichen Zahlen in IEEE 754. Einige Compiler bieten auch granularere Optionen für nur Reassoziation aktivieren. In jedem Fall ist der Programmierer vielen der oben erwähnten Präzisionsfallen für den Teil des Programms ausgesetzt, der "schnelle" Mathematik verwendet.

Bei einigen Compilern (GCC und Clang) kann das Einschalten der "schnellen" Mathematik dazu führen, dass das Programm beim Start subnormale Gleitkommazahlen deaktiviert , was sich auf das Gleitkomma-Verhalten nicht nur des generierten Codes, sondern auch jedes Programms auswirkt, das diesen Code als Bibliothek verwendet .

In den meisten Fortran- Compilern ist die Reassoziation gemäß dem Fortran-Standard ISO/IEC 1539-1:2004 die Standardeinstellung, wobei ein Bruch durch die Einstellung "parens schützen" (ebenfalls standardmäßig aktiviert) weitgehend verhindert wird. Diese Einstellung verhindert, dass der Compiler über die Grenzen der Klammern hinaus neu zuordnet. Intel Fortran Compiler ist ein bemerkenswerter Ausreißer.

Ein häufiges Problem in "schneller" Mathematik besteht darin, dass Unterausdrücke von Ort zu Ort möglicherweise nicht identisch optimiert werden, was zu unerwarteten Unterschieden führt. Eine Interpretation des Problems ist, dass "schnelle" Mathematik, wie sie implementiert ist, derzeit eine schlecht definierte Semantik hat. Ein Versuch, "schnelle" mathematische Optimierungen zu formalisieren, findet sich in Icing , einem verifizierten Compiler.

Siehe auch

Anmerkungen

Verweise

Weiterlesen

Externe Links