2009-08-16 6 views
1

Stellen Sie sich vor ich einen einfachen Taschenrechner-Anwendung schreiben, berechnet, dass nur einfache Sachen wieWann werde ich bei der Berechnung mit Doppelwerten auf Probleme stoßen?

1,5 + 30 + 9755 - 30 - 20000 + 999900,54

Ich erinnere mich an etwas, dass es einige Präzision Probleme waren bei der Verwendung von Gleitkommazahlen. An welchem ​​Punkt würde meine Taschenrechner-App falsche Ergebnisse erzeugen? Meistens würde ich ganze Zahlen wie 1 + 2 - 963422 berechnen, aber manchmal gebe ich eine Gleitkommazahl ein. Ich habe keine Ahnung, wo die Präzisionsprobleme anfangen würden zu wirken. nur die allerletzten Nummern dieses Doppel? wie -963419.0000000000003655? Oder wie würde das aussehen? Und irgendeine Idee, wie man diese fängt?

Antwort

5

Unter Berufung auf Wikipedia:

Neben Bedeutungsverlust, Unfähigkeit Zahlen darzustellen wie π und 0.1 genau und andere leichte Ungenauigkeiten, die folgenden Phänomene können auftreten:

  • Stornierung: Subtraktion von nahezu gleichen Operanden kann verursacht extremen Verlust der Genauigkeit. Dies ist vielleicht das häufigste und schwerwiegendste Genauigkeitsproblem der .
  • Conversions auf ganzzahlige nicht intuitiv: Umwandeln (63,0/9,0) zu ganzzahlige Ausbeuten 7, jedoch (0,63/0,09) ergeben kann 6. Dies ist da Konvertierungen allgemeinen trunkieren anstatt rund umwandelt. Boden und Decke Funktionen können Antworten produzieren, die durch einen aus dem intuitiven erwarteten Wert abweichen.
  • Begrenzter Exponentenbereich: Die Ergebnisse können überlaufen, was zu Unendlichkeit führt, oder Unterlauf, der eine subnormale Zahl oder Null ergibt. In diesen Fällen wird die Genauigkeit verloren gehen.
  • Testen für sichere Aufteilung ist problematisch: Überprüfen, dass der Divisor nicht Null ist, garantiert nicht, dass eine Division nicht überläuft und Unendlichkeit ergibt.
  • Testen auf Gleichheit ist problematisch. Zwei rechnerische Sequenzen, die mathematisch gleich sind, können durchaus unterschiedliche Fließkommawerte erzeugen. Programmierer oft Vergleiche innerhalb einiger Toleranz (oft eine Dezimalkonstante, selbst nicht genau dargestellt), , aber das macht nicht notwendigerweise das Problem verschwinden.

Um solche Probleme zu vermeiden, müssen Sie Ihre spezifische Berechnungen analysieren, um error propagation zu minimieren.

1

Gleitkommapräzision "Probleme" sind immer in jeder Gleitkommaberechnung vorhanden.

Manchmal haben Sie Glück und arbeiten mit Zahlen, die nur die Potenz von 2 haben: x.25, y.125 usw. Der Teil rechts vom Komma ist 1/(2^k) für jede ganze Zahl, k.

Wenn Sie mit einem Wert arbeiten, bei dem die Dezimalstellen keine Zweierpotenz sind, haben Sie Darstellungsprobleme. 1./3., 1./5., 1./6., 1./7., 1./9. Usw.

Fließkommadarstellungsprobleme treten bei alle non-power-of auf -2 Werte.

0

Es ist schwer zu sagen "wann", es hängt davon ab, wie groß/klein Ihre Zahlen sind, wie viele Operationen Sie ausführen und wie viel Präzision Sie benötigen.

Einige Sprachen unterstützen ein spezielles Objekt/Konstrukt zur Übergabe präziser Dezimaloperationen. Java hat BigDecimal: http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html

1

Fließkomma-Mathematik ist voller Fallstricke! Hier sind einige, auf die Sie achten sollten:

1) Hinzufügen von sehr großen und sehr kleinen (in absoluten Zahlen) Zahlen. IEEE-754 Gleitkommazahlen mit einfacher Genauigkeit haben etwa 7 signifikante Dezimalstellen der Genauigkeit. Also, wenn Sie versuchen, 1000000.0 + 3.14159 zu berechnen, werden Sie die meisten Ziffern nach dem Dezimalpunkt verlieren. Dies kann auftreten, wenn Sie einen naiven Algorithmus verwenden, um eine laufende Summe eines großen Arrays (Millionen von kleinen Werten) zu berechnen. Um einen besseren Weg zu sehen, sehen Sie sich Kahan summation an.

2) Es gibt ein ähnliches Problem beim Subtrahieren von zwei großen, fast gleichen Zahlen. Das Ergebnis darf nur ein oder zwei signifikante Zahlen haben. Auch hier besteht die Lösung darin, die Berechnung so zu ändern, dass "zwei Elefanten nicht abgezogen werden, um eine Maus zu bekommen".

0

Versuchen Sie 0.1 + 0.2 - 0.3.

+0

scheint kein Problem in Kakao-Touch. Ich bekomme 0.000000 als Ergebnis ... –

+0

Interessant zu sehen, ob das gleich 0 vergleicht. – AakashM

0

Für ein praktisches Beispiel, in IEEE754 32 Bit (Gleitkommazahl mit einfacher Genauigkeit) können die ganzen Zahlen nur bis zu 16777216 dargestellt werden, darüber gibt es Lücken. Die nächste Gleitkommazahl nach 16777216 ist 16777218.

+0

würde "double precision" (double) das lösen? –

+0

Das gleiche Phänomen existiert für alle Gleitkommazahlen, aber für das Doppelte sind die Zahlen viel größer. – starblue

+0

Bei doppelter Genauigkeit ist das Limit 2^53, was ungefähr 9 * (10^15) entspricht. –