32 Stimmen

Rundungsfehler?

In meinem Kurs wird mir das gesagt:

Kontinuierliche Werte werden im Speicher nur annähernd dargestellt, weshalb bei Berechnungen mit Fließkommazahlen Rundungsfehler auftreten. Dabei handelt es sich um winzige Abweichungen in den Bitmustern; daher ist der Test e==f unsicher ist, wenn e y f sind Schwimmer.

Bezogen auf Java.

Ist das wahr? Ich habe Vergleichsanweisungen verwendet mit double s und float s und hatten noch nie Rundungsprobleme. In einem Lehrbuch habe ich noch nie etwas Ähnliches gelesen. Die virtuelle Maschine trägt dem doch sicher Rechnung?

2voto

Artur Soler Punkte 2892

Ja, wie bereits in anderen Antworten gesagt wurde. Ich möchte hinzufügen, dass ich Ihnen diesen Artikel über die Genauigkeit von Fließkommazahlen empfehle: Visualisierung von Schwimmern

2voto

eipipuz Punkte 553

Natürlich ist das wahr. Denken Sie darüber nach. Jede Zahl muss im Binärformat dargestellt werden.

Bild: "1000" als 0,5 oder 1/2, also 2 ** -1. Dann ist "0100" 0,25 oder 1/4. Sie können sehen, worauf ich hinaus will.

Wie viele Zahlen können Sie auf diese Weise darstellen? 2**4. Wenn man weitere Bits hinzufügt, verdoppelt sich der verfügbare Platz, aber er ist nie unendlich. 1/3 oder 1/10 bzw. 1/n, jede Zahl, die kein Vielfaches von 2 ist, kann nicht wirklich dargestellt werden.

1/3 könnte "0101" (0,3125) oder "0110" (0,375) sein. Beide Werte sind, wenn man sie mit 3 multipliziert, nicht 1. Natürlich könnten Sie spezielle Regeln hinzufügen. Sagen Sie: "Wenn Sie 3 mal '0101' addieren, machen Sie daraus 1"... dieser Ansatz wird auf lange Sicht nicht funktionieren. Man kann zwar etwas auffangen, aber was ist dann mit 1/6 mal 2?

Es ist kein Problem der binären Darstellung, jede endliche Darstellung hat Zahlen, die man nicht darstellen kann, sie sind schließlich unendlich.

2voto

Nikolai Ruhe Punkte 80427

Die meisten CPUs (und Computersprachen) verwenden die Gleitkommaarithmetik nach IEEE 754. Bei dieser Notation gibt es Dezimalzahlen, die keine exakte Darstellung in dieser Notation haben, z. B. 0,1. Wenn Sie also 1 durch 10 dividieren, erhalten Sie kein exaktes Ergebnis. Wenn Sie mehrere Berechnungen hintereinander durchführen, summieren sich die Fehler. Probieren Sie das folgende Beispiel in Python aus:

>>> 0.1
0.10000000000000001
>>> 0.1 / 7 * 10 * 7 == 1
False

Das ist nicht wirklich das, was man mathematisch erwarten würde.

Nebenbei bemerkt: Ein häufiges Missverständnis in Bezug auf Fließkommazahlen ist, dass die Ergebnisse nicht präzise sind und nicht sicher verglichen werden können. Das stimmt nur, wenn Sie wirklich Bruchteile von Zahlen verwenden. Wenn die gesamte Mathematik im Integer-Bereich angesiedelt ist, tun Doubles und Floats genau dasselbe wie Ints und können auch sicher verglichen werden. Sie können z. B. sicher als Schleifenzähler verwendet werden.

1voto

dfa Punkte 110809

Ja, Java verwendet auch Fließkomma Arithmetik.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X