Mal wieder: double-Genauigkeit

Status
Nicht offen für weitere Antworten.
K

KaterKarlo

Gast
Hallo,
ich habe ein Problem. Ich rechne sehr viel mit double-Werten rum (so viel, dass ich es nicht komplett darlegen kann und möchte).
Beide Werte müßten am Ende der Berechnungen gleich sein, haben aber leider immer eine Differenz von 1.7E-14 bis 7.1E-15. Ich bin mir ziemlich sicher, dass dies durch Rundungsfehler o.ä. zustande gekommen ist.
Kann das überhaupt sein? Gibt es eine Möglichkeit, dies zu verhindern, ausser mittels Verwendung von BigDecimal?
Wie können solche Fehler entstehen?

Danke
 
K

KaterKarlo

Gast
Müßten Rundungsfehler nicht in einem kleiner Bereich sein?
 

0x7F800000

Top Contributor
KaterKarlo hat gesagt.:
Beide Werte müßten am Ende der Berechnungen gleich sein, haben aber leider immer eine Differenz von 1.7E-14 bis 7.1E-15.
Was soll uns das sagen? Ist das viel ist das wenig? Wenn du mit Zahlen wie "1,2,3,20,300" rechnest ist das extrem genau. Wenn du als Ergebnis 2.0E-15 +-1.7E-14 rausbekommst, dann hast du den totalen Müll ausgerechnet. Der absolute fehler sagt doch in diesem Fall absolut nichts aus.
Ich bin mir ziemlich sicher, dass dies durch Rundungsfehler o.ä. zustande gekommen ist.
Kann das überhaupt sein?
Das kann nicht nur sein, das muss sein. Selbst bei den einfachsten rationalen Zahlen, die nicht als Summen von kleinen Potenzen der 2 darstellbar sind, kriegst du sofort fehler in der Darstellung. Irrationale Zahlen kann man eh nicht auf diese Weise exakt handhaben.
Gibt es eine Möglichkeit, dies zu verhindern, ausser mittels Verwendung von BigDecimal?
Verhindern kann man das eh nicht. Ziehe die Wurzel aus der 2 und schon ist sowieso alles kaputt, da kannst du soviel Speicher reservieren wie du willst.
Du solltest dich entscheiden, was du für genauigkeit brauchst, und dann den passenden Typ der Fließkommazahlen wählen, und in dicken Büchern ein wenig nach möglichst numerisch stabilen Verfahren zur berechnung des jeweiligen Problems suchen.
Wie können solche Fehler entstehen?
Rechner können nicht rechnen. Rechner sind nur ein relativ dummes werkzeug. Der Mensch ist für's Rechnen verantwortlich. Wenn der Mensch ein schlechtes Verfahren implementiert, dann kriegt er auch Müll raus.
Garbage in - garbage out.
 

Marco13

Top Contributor
Wenn die Rechnungen, die du durchführst, laut IEEE754/854-Standard dieSELBEN Ergebnisse liefern müßten, dann kannst du dieses Verhalten ggf. erzwingen, indem du bei deinen Klassen und Methoden das Schlüsselwort "strictfp" hinzufügst. Allerdings bezweifle ich, dass es (bei nicht-trivialen Rechnungen, per Hand) möglich ist, zu verifizieren, dass die Ergebnisse dieSELBEN sein müßten. Wie groß die Fehler sind, hängt davon ab, wie groß die Zahlen sind, mit denen man rechnet, und welche Rechnungen man durchführt.
Code:
        double a = 1e-16f;
        double b = 1.0;
        if (a+b==1)
        {
            System.out.println("Tja... da kann man nichts machen...");
        }
 

Ebenius

Top Contributor
strictfp? Macht überhaupt keinen Unterschied, so lange man nicht auf zwei verschiedenen Maschinen läuft. strictfp führt eigentlich nur dazu, dass ggf. genauere Berechnungen einzelner Maschinentypen deaktiviert werden, so dass zwischen verschiedener Hardware/VM-Implementation genau kein Unterschied mehr besteht. Ob das in diesem Fall aber hilft?
 

Marco13

Top Contributor
Ohje - ein bißchen Halbwissen: Soweit ich weiß, rechnet Java unter Umständen (!) intern genauer - z.B. mit 80 bit für double. Die letzten Bits sind dabei u.U. ziemlich "zufällig". Wenn zwischendurch dann auch noch zwischen verschiedenen Threads umgeschaltet werden muss, kann da Kraut und RÜben rauskommen.l Dadurch KANN es sein, dass bei zwei aufeinanderfolgenden (oder parallelen) Ausführungen unterschiedliche Ergebnisse rauskommen. Wenn man strictfp verwendet, sollte IMMER GENAU nach IEEE-Standard gerechnet werden, und dann sollten die Ergebnisse auch vollkommen deterministisch immer gleich sein. War ja nur ein Tipp. Dass auch bei vollkommen strikter Einhaltung von IEEE (sinngemäß!) sowas wie
a = b - c;
b = -c + d;
theoretisch unterschiedliche Ergebnisse liefern kann, ist klar.
 

0x7F800000

Top Contributor
Marco13 hat gesagt.:
Dass auch bei vollkommen strikter Einhaltung von IEEE (sinngemäß!) sowas wie
a = b - c;
b = -c + d;
theoretisch unterschiedliche Ergebnisse liefern kann, ist klar.
bin ich hier der einzige, dem die Aussage irgendwie nicht ganz einleuchtet? ???:L
 

Ebenius

Top Contributor
Marco13 hat gesagt.:
Ohje - ein bißchen Halbwissen: Soweit ich weiß, rechnet Java unter Umständen (!) intern genauer - z.B. mit 80 bit für double.
Die Umstände sind VM-Implementation und Physikalisches System, jupp.

Marco13 hat gesagt.:
Die letzten Bits sind dabei u.U. ziemlich "zufällig". Wenn zwischendurch dann auch noch zwischen verschiedenen Threads umgeschaltet werden muss, kann da Kraut und RÜben rauskommen.l Dadurch KANN es sein, dass bei zwei aufeinanderfolgenden (oder parallelen) Ausführungen unterschiedliche Ergebnisse rauskommen.
Genau dafür hab ich nix gefunden. Gibt's dazu eine Referenz, z.B. einen Bug-Report bei Sun oder ein Artikel oder ähnliches? Ich weiß, dass es Unterschiede zwischen strict und nicht strict gibt; zum Beispiel können mit strict Overflows entstehen die ohne strict nicht passieren. Aber dass innerhalb der selben Maschine unterschiedliche Ergebnisse bei gleichen Algorithmen herauskommen kann daran IMHO nicht liegen...

Ein paar Minuten später ─ vor dem Absenden des Beitrages ─ fällt mir ein...
Bei non-strictfp macht recht sicher das da einen Unterschied, sofern es der Compiler nicht wegoptimiert:
Code:
final double a = ...;
final double b = ...;
final double c = ...;
.....
/* first example: multiply all values in one */
double resultA = a * b * c;

/* second example: assign the value in between */
double resultB = a * b;
resultB *= c;
^^ meintest Du sowas?

Java Programming Language Concepts »» 2.18 FP-strict Expressions
Sun TechTip: USING STRICTFP

Andrey hat gesagt.:
bin ich hier der einzige, dem die Aussage irgendwie nicht ganz einleuchtet? ???:L
Nein. :)

Ebenius
 

Marco13

Top Contributor
Diese unterschiedlichen Ergebnisse bei mehreren Ausführungen sind ersmal nur ein "Gerücht", das ich gehört habe (indizien habe ich auch, aber kein "kleines Testprogramm", bei dem reproduzierbare nicht-Reproduzierbarkeit auftritt :wink: ).
Ansonsten wollte ich primär auf das Problem der nicht-assoziativität und nicht-kommutativität hinweisen...
 
K

KaterKarlo

Gast
Hm, im Prinzip mach ich folgendes:
Ich rechne mit dem euklidischen Abstand von zufälligen Punkten im Intervall [0:1] herum.
Zu deutsch: Ich muß mit der Ungenauigkeit leben, richtig?
 

0x7F800000

Top Contributor
KaterKarlo hat gesagt.:
Ich rechne mit dem euklidischen Abstand von zufälligen Punkten im Intervall [0:1] herum.
Zu deutsch: Ich muß mit der Ungenauigkeit leben, richtig?
Das hört sich nicht gerade nach einer mordskomplizierten Rechnung an :)
Könntest du den entsprechenden Ausschnitt zeigen, wo deiner meinung nach irgendwas schief läuft?
Bist du dir sicher, dass es nicht an den zufällig gewählten Zahlen liegt? ???:L
 
G

Guest

Gast
Äh, natürlich liegt es an den Zufällig gewählten Zahlen.
Beispiel: dist( (0,1), (1,0) ) = sqrt(2);
Da die Punkte Zufällig sind, lassen sich Zahlen mit unendlicher Nachkommastellenentwicklung nicht vermeiden.
Leider ist mein Code nicht so einfach. Ich rechne viel mit A* rum.

Wie sähe denn Code aus, der bei Nachkommastellen aus dem Tritt kommt?
Ich schaffe es nicht, ein einfaches Programm zu schreiben, was über einen Nachkommastellenfehler stollpert und zum Beispiel ungleichheit ausgibt, obwohl mathematisch gesehen, die Zahlen gleich sein müßten.
 

0x7F800000

Top Contributor
Anonymous hat gesagt.:
Äh, natürlich liegt es an den Zufällig gewählten Zahlen.
Beispiel: dist( (0,1), (1,0) ) = sqrt(2);
Da die Punkte Zufällig sind, lassen sich Zahlen mit unendlicher Nachkommastellenentwicklung nicht vermeiden.
Leider ist mein Code nicht so einfach. Ich rechne viel mit A* rum.

Wie sähe denn Code aus, der bei Nachkommastellen aus dem Tritt kommt?
Ich schaffe es nicht, ein einfaches Programm zu schreiben, was über einen Nachkommastellenfehler stollpert und zum Beispiel ungleichheit ausgibt, obwohl mathematisch gesehen, die Zahlen gleich sein müßten.
Gast Gast Gast... Das verwirrt mich jetzt ziemlich... :bahnhof:
Wenn du nicht der OP bist, was hat dann der Erste teil deines Beitrages zu bedeuten?
Wenn du der OP bist, warum stellst du dir selbst die Frage die du oben schon gestellt hast?

Auf jeden Fall ist es mir schleierhaft, welche Rolle die fünfzehnte Nachkommastelle beim A* spielen soll :shock:
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Schon wieder double -.- Java Basics - Anfänger-Themen 4
K Matrix wieder in double [][] umwandeln Java Basics - Anfänger-Themen 7
DrahtEck Schleife soll wieder da anfangen wo ich es möchte ! Java Basics - Anfänger-Themen 17
G JTree speichern und wieder einlesen Java Basics - Anfänger-Themen 5
W In alten Code zurück- und dort wieder zurechtfinden? Java Basics - Anfänger-Themen 17
I Passwort in Datenbank speichern um später wieder auszulesen Java Basics - Anfänger-Themen 5
Temsky34 Wie bekomme ich dieses Java-Warning wieder weg? Java Basics - Anfänger-Themen 2
T j.u.Scanner(Sys.in).nextLine() wieder schließen? Java Basics - Anfänger-Themen 5
f3mys Objektwerte in Liste speichern und wieder abrufen Java Basics - Anfänger-Themen 23
O Text mit Regex trennen und wieder zusammenbauen Java Basics - Anfänger-Themen 5
Naxon89 Input/Output Ein PDF in einem BLOB umwandeln um ihn dann als PDF wieder anzuzeigen Java Basics - Anfänger-Themen 3
H JavaFX Hintergrundfarbe ändern, warten, Hintergrundfarbe wieder ändern Java Basics - Anfänger-Themen 34
MichelNeedhelp Brauche zu diesem Labyrinth ein Skript? Der Hamster soll im Urzeigersinn das ganze Labyrinth abgehen und wieder an seinem Ursprungsplatz sein. Java Basics - Anfänger-Themen 40
D Codeblöcke, die immer wieder im Programmverlauf benötigt werden Java Basics - Anfänger-Themen 5
TimoN11 Array -> Schleife wieder von vorne durchlaufen lassen Java Basics - Anfänger-Themen 1
JD_1998 Arrays einlesen, zwischenspeichern und wieder ausgeben Java Basics - Anfänger-Themen 8
M Regex Probleme (mal wieder) Java Basics - Anfänger-Themen 3
J Selektiertes Element von jComboBox zwischenspeichern und wieder einsetzen Java Basics - Anfänger-Themen 0
S Nutzereingabe splitten und in string array wieder ausgeben. Java Basics - Anfänger-Themen 1
I wieder mit einer Umwandelung habe ich Problem (diesmal von char Array zu char) Java Basics - Anfänger-Themen 1
N Wie kann ich einen String wieder zusammensetzen und ausgeben lassen? Java Basics - Anfänger-Themen 9
C Array-Eintrag wieder auf Null setzen Java Basics - Anfänger-Themen 3
W Verschachtelte Objekte wieder auspacken Java Basics - Anfänger-Themen 3
M Array immer wieder um ein Element erweitern Java Basics - Anfänger-Themen 6
CptK Methoden Event bei gedrückter Maustaste immer wieder ausführen Java Basics - Anfänger-Themen 1
CptK Klassen Event bei gedrückter Maus immer wieder mit Pause ausführen Java Basics - Anfänger-Themen 2
J Geld speichern und wieder auslesen Java Basics - Anfänger-Themen 10
M JTextField blitzt immer wieder nur auf Java Basics - Anfänger-Themen 12
CptK Datentypen Verdrehte Wörter wieder herstellen Java Basics - Anfänger-Themen 21
J Timer bauen, Main Methode immer wieder neu starten Java Basics - Anfänger-Themen 13
I Methoden Schleife immer wieder durchlaufen lassen Java Basics - Anfänger-Themen 15
F Immer wieder gleiche Zufallszahl? Java Basics - Anfänger-Themen 4
M Schleifenergebnis in selbiger wieder verwenden Java Basics - Anfänger-Themen 7
L Methoden Rekursion gibt alten Wert wieder Java Basics - Anfänger-Themen 37
L jar, class, java und wieder zurück Java Basics - Anfänger-Themen 8
M aus Fenster anderes Fenster öffnen und wieder umgekehrt Java Basics - Anfänger-Themen 5
J Fenster wieder unsichtbar machen Java Basics - Anfänger-Themen 2
J Auslesen/speichern und wieder einlesen Java Basics - Anfänger-Themen 7
S Sound stoppen und nach Pause wieder abspielen Java Basics - Anfänger-Themen 6
T while schleife starten , beeneden und wieder Starten Java Basics - Anfänger-Themen 8
I Zähler, der erst wieder zählt nachdem Pixel wieder andere Farbe hat Java Basics - Anfänger-Themen 2
B javax.ejb.Timer wieder starten? Java Basics - Anfänger-Themen 0
N Methode auslagern mal wieder Java Basics - Anfänger-Themen 8
F Inhalt einer Variable auswerten, die sich immer wieder ändert Java Basics - Anfänger-Themen 1
B ja ja schon wieder einer mit einer public static void main(string[] args) Frage... Java Basics - Anfänger-Themen 8
Bluedaishi for schleife um Dateien wieder zusammen zu fügen Java Basics - Anfänger-Themen 11
I SHA512 verschlüsseln und dann wieder auslesen? Java Basics - Anfänger-Themen 35
F Timer abbrechen und wieder starten Java Basics - Anfänger-Themen 5
J KeyListener - mal wieder... Java Basics - Anfänger-Themen 2
B Listener beim Laden (deserialize) wieder hinzufügen bzw. mitspeichern? Java Basics - Anfänger-Themen 3
GadgetSofa .txt Datei erstellen und gleich wieder Löschen? Java Basics - Anfänger-Themen 12
D Bild für ein paar Sekunden einblenden und wieder ausblenden Java Basics - Anfänger-Themen 1
M Tabelle aktualisieren (mal wieder) Java Basics - Anfänger-Themen 10
M Erste Schritte Tabelle aktualisieren (mal wieder) Java Basics - Anfänger-Themen 7
M Zahlen als Bytes in eine Datei speichern, daraus wieder auslesen Java Basics - Anfänger-Themen 2
R Switch: Nach durchlaufen des Case wieder zum Menü Java Basics - Anfänger-Themen 3
K For Each Schleife wieder von Beginn an iterieren Java Basics - Anfänger-Themen 12
L Und schon wieder :=( Java Basics - Anfänger-Themen 3
T Arbeitsspeicher wieder freigeben Java Basics - Anfänger-Themen 21
Ernesto95 BufferedImage Teilbereich wieder transparent setzen Java Basics - Anfänger-Themen 16
J Schon wieder Rekursionsproblem Java Basics - Anfänger-Themen 3
S Erste Schritte Hochgescrolltes Menu nach MouseOut wieder "runter holen" Java Basics - Anfänger-Themen 3
H Datei in kleine Stücke teilen und wieder erkennen Java Basics - Anfänger-Themen 10
B Variable wird einfach so wieder auf "null" gesetzt Java Basics - Anfänger-Themen 12
B Cookies auslesen und wieder schreiben Java Basics - Anfänger-Themen 2
T wieder mal Serialization :-) Java Basics - Anfänger-Themen 10
J Mal wieder ein kleines Toleranzproblem Java Basics - Anfänger-Themen 20
T text von textfeld auslesen und wieder reinschreiben Java Basics - Anfänger-Themen 10
T Benutzereingabe in form von string wieder ausgeben in JOptionPane Java Basics - Anfänger-Themen 14
F Input/Output ArrayList presistent speichern und wieder auslesen Java Basics - Anfänger-Themen 4
D Ausgegebene Worte wieder löschen. Java Basics - Anfänger-Themen 6
B Heap-Speicher wieder freigeben Java Basics - Anfänger-Themen 10
P Mal wieder JTable Java Basics - Anfänger-Themen 7
V Schon wieder ein kleines problem...dieses mal mit do-while loop Java Basics - Anfänger-Themen 9
M Mal wieder Probleme mit Date Java Basics - Anfänger-Themen 9
M Threads Thread ist nur kurz interrupted, dann wieder nichtmehr Java Basics - Anfänger-Themen 6
K Mal wieder ein Problem mit If / Else Java Basics - Anfänger-Themen 10
A Wie kann man etwas von Typ Image wieder löschen? Java Basics - Anfänger-Themen 7
J Threads Threads anhalten und wieder fortführen Java Basics - Anfänger-Themen 9
P Dropdownbox nach hinzufügen wieder öffnen Java Basics - Anfänger-Themen 7
A Daten speichern und wieder in ein Array laden Java Basics - Anfänger-Themen 4
B Datentypen Inhalt zum Iterator wieder aufrufen? Java Basics - Anfänger-Themen 10
Os-Programming Checkbox immer wieder überprüfen Java Basics - Anfänger-Themen 13
S Datei einlesen und Ergebnis wieder in Datei schreiben Java Basics - Anfänger-Themen 5
J Datei einlesen teile aus lines ändern und wieder rausschreiben. Java Basics - Anfänger-Themen 4
M String-Array-Element wieder null zuweisen Java Basics - Anfänger-Themen 16
K Wie kann ich aus jar Dateien wieder normale Klassen generieren? Java Basics - Anfänger-Themen 7
F Mal wieder: Cannot make a static reference to the non-static method Java Basics - Anfänger-Themen 9
F Collections Datenbankdaten in einer Map speichern, bearbeiten, sortieren und wieder in Datenbank schreiben Java Basics - Anfänger-Themen 20
B Datentypen Werte in einen Array einlesen und danach die beiden höchsten Werte wieder ausgeben Java Basics - Anfänger-Themen 3
L Datentypen byte[] in String und wieder zurück Java Basics - Anfänger-Themen 3
B Datei in mehrere Ordner splitten und wieder zusammenfuegen... Java Basics - Anfänger-Themen 3
R ARRAY/List die sich immer wieder von vorne neu auffüllt ? Java Basics - Anfänger-Themen 21
F OOP Wieder mal Zugriffsprobleme... (Lösung am Ende) Java Basics - Anfänger-Themen 11
M Dynamisches Casten mal wieder Java Basics - Anfänger-Themen 4
P Zwei Charakter als Paramter übergeben und wieder ausgeben Java Basics - Anfänger-Themen 10
D Array speichern und wieder aufrufen Java Basics - Anfänger-Themen 6
Dit_ Thread stoppen und wieder starten Java Basics - Anfänger-Themen 2
M AudioStream - wiederholen, pausieren und wieder starten Java Basics - Anfänger-Themen 2
U Threads - Beenden/ Wieder starten Java Basics - Anfänger-Themen 10

Ähnliche Java Themen

Neue Themen


Oben