Redimp's Blog
21Oct/091

(Rundungs-)Fehler

Maschinengenauigkeit und aus der Maschinenungenauigkeit resultierende Rundungsfehler sind in der Numerik schon in den ersten Vorlesungen ein Thema. Bei einfacher Genauigkeit ist schon irgendwo bei 6 \cdot 10^{-8} Schluss, bei doppelter erst bei 10^{-16}.

Gestern Abend musste ich feststellen, dass mir meine Rechnung um die Ohren fliegt, wenn ich 1/3 an meine Matrix multipliziere. Die Matrix liess sich aufstellen, und da gab es auch keinerlei Probleme, nur der Loeser hat danach nur noch Unsinn gemacht. Ich habe es spasseshalber mal versucht dieses Epsilon auf der Konsole als Parameter uebergeben, statt das Drittel fest zu verdrahten, ... und mit -eps 0.333333 lief die Rechnung froehlich vor sich hin und in die richtige Richtung. Tja, dann habe ich es mit -eps 0.3333333 versucht und wieder: Alles im Lot. Bei -eps 0.33333333 (8 Stellen hinter dem Komma) knallte es dann endlich: Der Loeser rannte froehlich in die falsche Richtung. Irgendwo musste sich ein float in meiner Rechnung versteckt haben, vielmehr ein Zwischenrechenschritt musste mir die doppelte Genauigkeit kaputt gemacht haben. So einen Fehler zu suchen, das macht keinen Spass.

Ich habe mir zum Glueck erst die gespeicherten Matrizen angeguckt bevor ich wirklich tief in die Fehlersuche eingestiegen bin. Diese lege ich in Dateien ab, damit ich sie nicht fuer jede Rechnung neu aufstellen muss. Da wir hier verschiedene Architekturen haben und somit double unterschiedlich lang sein koennen, habe ich es fuer eine gute Idee gehalten, die Dateien einfach als ASCII Files abzulegen. Und da lachte mich auch schon mein Fehler an:

// configure outputstream: write in x.yEz format with precision 8
ost << std::scientific << std::setprecision(8);

Ich speichere die Matrizen jetzt wieder binaer via

ost.write( reinterpret_cast( &d ), sizeof d); // double d

Man kann sich die Genauigkeit auch mit allen Mitteln kaputt machen. Man muss nur wollen.