Gleitkomma-Ungenauigkeit in C
Gleitkomma-Arithmetik in der Programmierung beinhaltet die Darstellung reeller Zahlen mithilfe einer festen Anzahl von Bits, was zu potenziellen Ungenauigkeiten führen kann . Dieser Artikel befasst sich mit Präzisionsproblemen bei C-Gleitkommaoperationen, beispielhaft dargestellt durch den folgenden Code:
<code class="cpp">double a = 0.3; std::cout.precision(20); std::cout << a << std::endl;
Dieser Code gibt 0,2999999999999999889 anstelle der erwarteten 0,3 aus. Wenn außerdem a 50-mal zu sich selbst addiert wird, beträgt das Ergebnis 15,000000000000014211 statt der erwarteten 15.
Erklärung
Gleitkommazahlen haben eine begrenzte Genauigkeit, bestimmt durch ihre Bitzahl. Gleitkommazahlen mit doppelter Genauigkeit haben 53 Bits für den Bruchteil, was zu einer effektiven Genauigkeit von etwa 15 Dezimalstellen führt.
Bei Verwendung von std::cout.precision(20) weisen Sie den Stream an, 20 Stellen von anzuzeigen Präzision. Der zugrunde liegende Wert von a hat jedoch nur eine Genauigkeit von 15 Stellen. Die zusätzlichen Ziffern werden mit Nullen aufgefüllt, was zu Ungenauigkeiten führt.
Das zweite Beispiel akkumuliert die Ungenauigkeiten wiederholter Additionen. Da Gleitkomma-Arithmetik nicht assoziativ ist, können leicht unterschiedliche Additionsfolgen zu leicht unterschiedlichen Ergebnissen führen.
Lösung
Um den Präzisionsverlust zu minimieren, setzen Sie nicht std:: cout.precision ist höher als die verfügbare Genauigkeit des numerischen Typs. Dies kann wie folgt erreicht werden:
<code class="cpp">std::cout.precision(std::numeric_limits<double>::digits10);</code>
Dies begrenzt die Genauigkeit auf 15 Stellen für Gleitkommazahlen mit doppelter Genauigkeit.
Bei einer großen Anzahl sich wiederholender Berechnungen können jedoch immer noch akkumulierte Fehler auftreten. In solchen Fällen werden alternative Techniken wie Festkommaarithmetik oder die Verwendung von Brüchen mit ganzzahligen Zählern und Nennern empfohlen.
Das obige ist der detaillierte Inhalt vonWarum wird „0,3' in C zu „0,2999999999999999889'?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!