Nutzen von Fließkommazahlen



  • Man kann Haare spalten. Dann werden aus einem Haar zwei oder mehr. Die Diskussion hier ist so ähnlich und trifft nicht die Fragestellung.

    Fliesskommazahlen sind sehr genau, genauer als alles andere. Nur nicht in der allerletzten Stelle hinter dem Komma. Das was hier als Festkommazahlen offeriert wird sind entweder gerundete Fliesskommazahlen oder simple Ganzzahlen mit Multiplikation. Ganzzahlen haben viel früher eine Grenze der Genauigkeit.



  • seldon schrieb:

    und auch da ist es so, dass ein Rundungsfehler bei 15 Stellen Genauigkeit sich auch bei Milliardenbeträgen höchstens auf einen Cent beläuft.

    Das Problem ist eher die Fehlerfortpflanzung, wodurch die deutlich größere Fehler bekommen kannst.


  • Administrator

    SeppJ schrieb:

    Dravere schrieb:

    Für technische Rechnungen, welche wirklich genau sein müssen, würde ich auch nicht Gleitkommazahlen heranziehen.

    Ich bin allgemein etwas verwirrt über die Ansichten hier im Thread und über diese Aussage ganz besonders. Kannst du mir mal ein Beispiel nennen für welche technische Anwendung double nicht ausreichend sein soll? Für float kann ich noch ein paar Gegenbeispiele konstruieren, aber auch dies sind schon seltene Ausnahmefälle.

    Es geht um die Art, wie mit Gleitkommazahlen gerechnet wird. Es entstehen die ganze Zeit leichte Ungenauigkeiten, welche sich über die Zeit aufsummieren. Ich hatte erst letzten wieder ein Problem mit double . Es ging darum eine Simulation zu schreiben, wobei double verwendet wurde für die Positionsangaben (war nicht meine Entscheidung!). Dabei sind bereits auf Distanzen von 3-5 Metern Abweichungen von 1-5 Grad aufgetreten. Wenn man dies auf dein Beispiel mit der Rakete hochrechnet, dann würdest du wohl Gefahr laufen, bei der Landung neben der Erde durchzufliegen 😉

    Man muss nie vergessen, dass Gleitkommazahlen nur eine Approximation des gewollten Wertes darstellen und immer einen gewissen Fehlerwert mitführen. In grossen Rechnungen, welche dann womöglich auch noch oft gemacht werden, werden diese Fehler immer wieder mitgeführt und fangen an sich zu summieren. Es geht also nicht um die Darstellung einer einzelnen Zahl!

    SeppJ schrieb:

    Viele der Probleme die hier aufgezählt werden erinnern mich daran, wie wenn Anfänger Kontonummern, Postleitzahlen oder Telefonnummern als Ganzzahlen speichern und dann in Schwierigkeiten kommen. Der Fehler liegt in der falschen Modellierung (eine Ziffernfolge ist keine Zahl!), nicht im Datentyp.

    Daran erinnert mich der Thread irgendwie überhaupt nicht. Das ist doch ein ganz anderes Problem. Wie gesagt, es geht nicht um die Darstellung einer Zahl, sondern um das Rechnen mit dieser Zahl. Ich glaube eher, dass genau dies das Problem von einigen hier ist. 15-16 Stellen Genauigkeit bei der Darstellung, heisst nicht, dass auch das Ergebnis einer Rechnung eine Genauigkeit von 15-16 Stellen hat.

    Grüssli



  • Also nachdem ich das bei Wikipedia gelesen habe, bleibe ich dabei Gleitkomma nur einzusetzen wenn das Ergebnis nicht genau sein muss.

    Gab es nicht auch schon Probleme wenn man mit 0.1 oder so rechnen muss? Das kannst du dann 10 mal addieren und kommst aber nie auf 1. Das konnte ich zwar bei mit nicht feststellen, ist aber wohl in Excel mit VBA so. Also diese Zahlen sind wohl wirklich mit größter Vorsicht zu geniessn.


  • Mod

    hibbes schrieb:

    Also nachdem ich das bei Wikipedia gelesen habe, bleibe ich dabei Gleitkomma nur einzusetzen wenn das Ergebnis nicht genau sein muss.

    Gab es nicht auch schon Probleme wenn man mit 0.1 oder so rechnen muss? Das kannst du dann 10 mal addieren und kommst aber nie auf 1. Das konnte ich zwar bei mit nicht feststellen, ist aber wohl in Excel mit VBA so. Also diese Zahlen sind wohl wirklich mit größter Vorsicht zu geniessn.

    Nein, sind sie nicht. Wenn dein Zahlenraum nur aus Zehntelwerten besteht, dann hast du den falschen Datentyp gewählt. Wenn du hingegen mit reellen Zahlen recchnen willst, dann ist die Abweichung egal. Wen interessiert, dass 10 Holzstücke a 0.1m hintereinandergelegt in Fließkommaarithmetik 0.9999999999999999999 m sind und nicht 1m? Niemand wird jemals solch präzise Werkstücke oder Maßstäbe fertigen um den Unterschied zu messen.
    (Ok, derzeit stoßen wir in diese Dimensionen vor. Die am genauesten bekannten physikalischen Größen knabbern derzeit an der 15-Stellen-Grenze. Will man theoretische Rechnungen mit diesen Größen machen (welche keine ungenaueren Größen enthalten), dann muss man einen noch genaueren Datentyp wählen. Das ändert aber nichts daran, dass Fließkommazahlen dennoch die richtige Wahl sind, denn niemanden stört es, dass das long-double Ergebnis hinterher in der 30. nachkommastelle Fehler hat.)

    @Dravere: Das ist interessant. Ich mache ja selber auch physikalische Simulationen und hatte nie solche Probleme. War vielleicht der Algorithmus ungeeignet? Oder war eine unglaublich große Zahl von Rechenschritten (mehr als 10^10) nötig? Dennoch ist die Lösung für solche Probleme nur eine höhere Fließkommapräzision. Die ach so exakten Ganzzahlen würden alles nur schlimmer machen, denn Positionsangaben sind nun einmal kontinuierlich und daher FLießkommazahlen das geeignete Computermodell (Wenn ihr keine Gittertheorie macht. Dann wäre das falsch.).



  • SeppJ schrieb:

    Das ändert aber nichts daran, dass Fließkommazahlen dennoch die richtige Wahl sind, denn niemanden stört es, dass das long-double Ergebnis hinterher in der 30. nachkommastelle Fehler hat.

    Ist es nicht so, dass bei long double nur der Exponent größer wird, die Mantisse aber immer noch 4 Byte lang ist?



  • Hmm, scheint ja dann doch zu funktionieren wenn man rundet. Aber wie sieht es bei Gleichungen aus wenn ich eine 1.0 mit der 0.999999999999 vergleiche? Muss man da nicht extremst aufpassen?



  • hibbes schrieb:

    Hmm, scheint ja dann doch zu funktionieren wenn man rundet. Aber wie sieht es bei Gleichungen aus wenn ich eine 1.0 mit der 0.999999999999 vergleiche? Muss man da nicht extremst aufpassen?

    Musst du, deswegen wird empfohlen, mit einem gewissen Abweichungswert zu vergleichen:

    bool equal(double a, double b)
    {
        return fabs(a-b) <= std::numeric_limits<double>::epsilon;
    }
    


  • Super danke, das kannte ich auch noch nicht. Kommt gleich in die Notizen 👍



  • wxSkip schrieb:

    Musst du, deswegen wird empfohlen, mit einem gewissen Abweichungswert zu vergleichen:

    bool equal(double a, double b)
    {
        return fabs(a-b) <= std::numeric_limits<double>::epsilon;
    }
    

    Ja, aber nicht mit epsilon , sondern einer dem konkreten Problem angepassten Toleranz. epsilon bezeichnet nur die Differenz zwischen 1 und dem nächstgrösseren darstellbaren Wert.



  • Nexus schrieb:

    wxSkip schrieb:

    Musst du, deswegen wird empfohlen, mit einem gewissen Abweichungswert zu vergleichen:

    bool equal(double a, double b)
    {
        return fabs(a-b) <= std::numeric_limits<double>::epsilon;
    }
    

    Ja, aber nicht mit epsilon , sondern einer dem konkreten Problem angepassten Toleranz. epsilon bezeichnet nur die Differenz zwischen 1 und dem nächstgrösseren darstellbaren Wert.

    OK, aber im Fall von 0.999999999999999 passt das schon 🙂



  • Dravere schrieb:

    Ich habe dies nicht für technischwissenschaftliche Rechnungen vorgeschlagen, sondern für Währungsrechnungen, also für die Verwendung in der Finanzwirtschaft und genau dafür wurden diese zusätzlichen Gleitkommazahlen geschaffen.

    Wie schön, daß Du nicht einmal merkst, daß exakt in dem von Dir geschlagenem Anwendungsfeld es trotzdem die schon erwähnten Probleme gibt!



  • seldon schrieb:

    Und da sind 15 Stellen Genauigkeit mehr als ausreichend, zumal vieles eh Ansichts- oder Konventionssache ist.

    Fehlerfortpflanzung ist wohl für viele ein Fremdwort. 15 Stellen Genauigkeit wären wundervoll, wenn ein jedes Ergebnis damit ausgegeben würde. Allerdings ist die effektive Genauigkeit bei einer Berechnung oftmals sehr viel geringer, und der Rest der Stellen im Grunde nur Rauschen des Algorithmus. Das wird leider viel zu oft vergessen.



  • Kann man denn nicht irgendwie festmachen für was man Gleitkommazahlen ohne Einschränkung und besonderer Behandlung nutzen kann und wo man sehr genau aufpassen sollte?


  • Administrator

    ~john schrieb:

    Dravere schrieb:

    Ich habe dies nicht für technischwissenschaftliche Rechnungen vorgeschlagen, sondern für Währungsrechnungen, also für die Verwendung in der Finanzwirtschaft und genau dafür wurden diese zusätzlichen Gleitkommazahlen geschaffen.

    Wie schön, daß Du nicht einmal merkst, daß exakt in dem von Dir geschlagenem Anwendungsfeld es trotzdem die schon erwähnten Probleme gibt!

    😕
    Willst du eigentlich alles bewusst falsch verstehen? Lies bitte nochmals, was ich wie geschrieben habe.
    Neue Gleitkommazahlen des neuen Standards mit höherer Genauigkeit und neuer Rechnungskonvention für die Finanzwirtschaft. So schwer zu verstehen? Ich sage nicht, dass dadurch alle Probleme eliminiert werden! Aber sie werden deutlich reduziert und reichen meistens für die Finanzen.

    @SeppJ,
    Ich kann deine Fragen schlecht beantworten. Das einzige, was ich dazu sagen kann, ist, dass Motoren simuliert wurden. In kleinen Intervallen (ca. 1 - 2 Millisekunden) wurde die Position der Motoren aktualisiert und danach über Odometrie die aktuelle Position des Vehikels berechnet. Die Motoren hatten eine sehr geringe Geschwindigkeit (0,1 - 0,4 m/s). Auch ging es grundsätzlich immer um den Nullpunkt im 2D Raum, wodurch nie wirklich grosse Zahlen entstanden. Auch der Winkel wurde immer wieder nach einer 360° Umdrehung zurückgesetzt.

    Wir haben dann zum Teil mitgerechnet und festgestellt, dass nach jeder Rechnung ein kleiner Fehler entstand. Dieser Fehler wurde abgespeichert als Position und mit dieser Position dann die nächste berechnet, Odometrie eben 🙂
    Dadurch hat sich dieser Fehler immer fortgepflanzt und es kam zu der erwähnten Abweichung. Wir konnten den Fehler auf nichts anderes zurückführen.

    Am Projekt hat es nicht wirklich geschadet, da in der Realität die Motoren sowieso nicht durch einen einzigen Befehl gleichzeitig die Geschwindigkeit ändern konnten, sondern nur sequentiell von einer höheren Abstraktionsebene aus. Zudem liefen sie nicht genau gleich schnell. Daher haben wir in der Simulation gleich noch den Positionskorrektur-Code dazugeschaltet, welche wir aber eigentlich bei der Simulation nicht dabei haben wollten. Das war aber nur ein kleines Projekt, vielleicht haben wir wirklich was falsch gemacht.

    Aber wie ich weiter vorne gesagt habe, hatte ich mal double für Währungen eingesetzt. Ist allerdings schon länger her. Da gab es bereits bei Beträgen von mehreren Hunderttausend Abweichungen von 2 - 3 Cent. Spielte dort zwar keine Rolle, da der Betrag am Ende sowieso abgerundet wurde, da man keine xxxx.99 Rechnungen haben wollte. Die Kunden wurden somit nie irgendwie betrogen, die Firma hat aber über das Jahr ein paar Euro verloren 😉
    Wenn man die Beträge aber wirklich genau hätte haben wollen, so wäre double definitiv der falsche Typ gewesen, weil er einfach zu ungenau ist.

    Mir ist es ehrlich gesagt ein Rätsel, wie du bisher noch nie Probleme mit double haben konntest.

    Grüssli


  • Mod

    hibbes schrieb:

    Kann man denn nicht irgendwie festmachen für was man Gleitkommazahlen ohne Einschränkung und besonderer Behandlung nutzen kann und wo man sehr genau aufpassen sollte?

    Grob gesagt:
    - Rechnungen mit reellen (nicht nur rationalen!) Zahlen (oder allgemein kontinuierlichen Mengen) ➡ Fließkommatypen und aufpassen!

    - Rechnungen mit ganzen oder rationalen Zahlen (oder allgemein mit abzählbaren Mengen) ➡ Ganzzahltypen oder spezialisierte Klassen die auf Ganzzahltypen basieren. Es ist nicht soooo wichtig auszupassen wie bei Fließkommazahlen.

    Worauf man aufpassen muss:
    - Keine Vergleiche auf absolute Gleichheit
    - Fehlerfortpfanzung bei Rechnungen beachten, besonders wenn in Algorithmen bestimmte Rechenschritte sehr oft wiederholt werden. Eigentlich sollte jeder der mit Fließkommazahlen arbeitet mal eine Numerikvorlesung gehört oder dieses Dokument gelesen haben.
    - Eine große Sünde ist zum Beispiel das Subtrahieren von fast gleichen Zahlen. Bei einer Subtraktion summieren sich nämlich die absoluten Fehler. Wenn dann zusätzlich das Ergebnis klein ist, bekommt man einen riesigen relativen Fehler. Also die Rechnungen umstellen, dass so etwas nicht passiert. Wikipedia hat da ein schönes Beispiel

    @Dravere: Wie schon gesagt, ist Fließkomma eher der falsche Typ für Währungsrechnungen, weil Geldbeträge immer nur eine feste Anzahl Nachkommastellen haben. Und Sachen wie Zinsen sind normalerweise auch immer runde Dezimalbrüche.

    Warum ich nie Probleme hatte? Nun, ich habe bisher hauptsächlich Simulationen mit einem Wärmebad gemacht oder Monte Carlo Methoden benutzt. Beides ist robust gegen kleine Fehler, falls man Probleme bekommt sollte man den Zeitschritt verkleinern. Ansonsten auch immer darauf, ein gutes Verfahren zu benutzen. Integration nach Euler ist zum Beispiel denkbar schlecht für Dynamiksimulationen. Und auch bei anderen Verfahren muss man halt wissen, wann man besser aufhören sollte (ein Blick auf die Gesamtenergie hilft als Hinweis).



  • SeppJ schrieb:

    oder dieses Dokument gelesen haben.

    👍



  • wxSkip schrieb:

    Ist es nicht so, dass bei long double nur der Exponent größer wird, die Mantisse aber immer noch 4 Byte lang ist?

    Es ist von der jeweiligen Plattform abhängig was für ein Format mit long double verwendet wird. Zum Teil ist das das Intel 80Bit Format zuweilen auch 128Bit IEEE Quad.



  • Ich verstehe diese Diskussion um Gleitkommazahlen nun überhaupt nicht mehr. Dieser Datentyp bildet doch reelle Zahlen mit Mantisse und Exponent sehr genau ab und dafür gibt es ihn seitdem programmiert wird. Eine Abfrage auf Gleichheit erfolgt natürlich mit dem Absolutwert auf einen als hinreichend genau betrachteten Wert Epsilon. In der Finanzmathematik gibt es zwangsläufig Probleme, wenn die Saldi in Cent sein sollen und die dazwischen mit Gleitkomma erfolgten Berechnungen genauer sind.

    Da soll schon mal jemand mit Zinsberechnungen und unauffälligen Rundungen sich selbst bereichert haben. Es ging, flog aber dennoch auf!



  • Dravere schrieb:

    Willst du eigentlich alles bewusst falsch verstehen?

    Du schreibst auch weiterhin Falsches, da gibt es nichts "absichtlich" falsch zu verstehen. Bei Verwendung von Dezimalarithmetik wird lediglich das Problem der Konvertierung vermieden. Alle anderen Probleme des Rechnens mit Gleitkommaarithmetik existieren weiterhin!

    Dravere schrieb:

    Ich sage nicht, dass dadurch alle Probleme eliminiert werden! Aber sie werden deutlich reduziert und reichen meistens für die Finanzen.

    Und genau hier liegt das fundamentale Problem, Du siehst die Probleme mit Gleitkommaarithmetik nicht.


Anmelden zum Antworten