Nutzen von Fließkommazahlen



  • Ok, der Fehler war mehr als blöd. Warum gibt cout keine Gleitkommazahlen direkt aus?



  • _malsogefragt schrieb:

    Für was werden denn Fließkommazahlen eingesetzt wenn sie so ungenau sind?

    Gleitkommarithemtik wird immer dann verwendet, wenn man für technischwissenschaftliche Rechnungen eine Approximation von reellen oder komplexen Zahlen benötigt. Natürlich treten dabei Probleme auf, aber es gehört nun einmal zu den Aufgaben eines Naturwissenschaftlers oder Ingenieurs zu wissen, wann dies der Fall ist.

    Festkommazahlen sind keine Alternative für SciTech Rechnungen, da sie viel zu langsam sind. Finanzmathematische Rechnungen werden dagegen nicht mit Gleitkommaarithmetik gerechnet.



  • hibbes schrieb:

    Ok, der Fehler war mehr als blöd. Warum gibt cout keine Gleitkommazahlen direkt aus?

    Doch, das ist der Fall. Nur wird bei der Ausgabe gerundet.



  • Dravere schrieb:

    Es gibt inzwischen bessere Fliesskommazahlen, welche sehr viel genauer sind und auch keine ungewollten Rundungen beinhalten. In C# gibt es zum Beispiel dazu System.Decimal . IEEE Standards wären hier 854-1987 und 754-2008 zu nennen.

    Das ist schlichtweg falsch! Dezimalgleitkommazahlen unterliegen bis auf eine Ausnahme exakt den gleichen Problemen wie die Binärgleitkommazahlen. Einzig das Problem der Nichtabbildbarkeit einiger Dezimalbrüche auf Binärbrüche und umgekehrt wird mit Dezimalgleitkommazahlen vermieden. Trotzdem muß man bei Verwendung der Dezimalgleitkommaarithmetik genauso aufpassen wie mit der Binärgleitkommarithmetik. Hinzu kommt, daß man durch die Dezimalkodierung noch etwas an Genauigkeit verliert. Daher empfiehlt sich das Dezimalformat nicht für technischwissenschaftliche Rechnungen.



  • Schön dass sich alle bei den einfachsten grundlegenden Datentypen so einig sind wie sie funktionieren 😃 Ich würde mal sagen zurück zum Start beim Programmieren lernen 😃 😃 😃



  • ???????? schrieb:

    Schön dass sich alle bei den einfachsten grundlegenden Datentypen so einig sind wie sie funktionieren.

    Die meisten Informatiker setzen sich mit Gleitkommaarithmetik nun einmal nicht wirklich auseinander. Es hat seien Gründe warum man Gleitkommaarithemtik mit Binär- und Dezimalformat, Intervalarithmetik auf Basis von Binärgleitkommaarithemtik, Libraries/Framworks für Gleitkomma mit beliebiger Genauigkeit, Festkommarithmetik und Integerarithmetik verwendet.


  • Administrator

    ~john schrieb:

    Das ist schlichtweg falsch! Dezimalgleitkommazahlen unterliegen bis auf eine Ausnahme exakt den gleichen Problemen wie die Binärgleitkommazahlen. Einzig das Problem der Nichtabbildbarkeit einiger Dezimalbrüche auf Binärbrüche und umgekehrt wird mit Dezimalgleitkommazahlen vermieden. Trotzdem muß man bei Verwendung der Dezimalgleitkommaarithmetik genauso aufpassen wie mit der Binärgleitkommarithmetik. Hinzu kommt, daß man durch die Dezimalkodierung noch etwas an Genauigkeit verliert. Daher empfiehlt sich das Dezimalformat nicht für technischwissenschaftliche Rechnungen.

    Schön wie du Sachen aus dem Kontext reisst und dann auch noch Dinge fett machst, sieht wirklich nett aus. 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.
    Für technische Rechnungen, welche wirklich genau sein müssen, würde ich auch nicht Gleitkommazahlen heranziehen.

    hibbes schrieb:

    Ok, der Fehler war mehr als blöd. Warum gibt cout keine Gleitkommazahlen direkt aus?

    Wie ~john gesagt hat, wird gerundet. Gibt aber die Möglichkeit mehr Kontrolle darüber zu haben:
    http://www.cplusplus.com/reference/iostream/ios_base/precision/

    Hättest du in einem von mir präsentierten Code in diesem Thread bereits schon gesehen. Zusätzlich seien noch erwähnt:
    http://www.cplusplus.com/reference/iostream/manipulators/fixed/
    http://www.cplusplus.com/reference/iostream/manipulators/scientific/

    Grüssli


  • Mod

    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.

    Zum Thread: Wie ich im ersten Beitrag schon sagte: Niemand verwendet Fließkommazahlen nicht wegen mangelnder Genauigkeit. Man verwendet Fließkommazahlen nur dann nicht, wenn das Problem inhärent nach einem diskreten Zahlenmodell verlangt (z.B. Geld). Ich denke das Problem ist eher, dass viele Leute nicht wissen, wie man Sachen richtig modelliert. Sie sehen eine Zahl mit einem Komma drin und denken nur "Oh, da muss ich Fließkommazahlen nehmen", obwohl dies eigentlich gar nicht angemessen wäre. Fließkommazahlen sind die Digitalcomputerannäherung für das Kontinuum (mit ein paar Fallstricken auf die man aufpassen muss). Das Komma ist nicht das entscheidende Feature!

    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.



  • ~john schrieb:

    Finanzmathematische Rechnungen werden dagegen nicht mit Gleitkommaarithmetik gerechnet.

    Das ist so nicht ganz korrekt. Gleitkommazahlen sind eine schlechte Idee, wenn es um Geldbeträge geht und Haargenauigkeit verlangt wird - wenn auf einer Rechnung nicht genau der vereinbarte Preis steht, ist das ziemlich peinlich - aber in der Finanzmathematik, wie sie beispielsweise im Wertpapierhandel betrieben wird, sind die meisten relevanten Größen betragsneutral. Wenn ein Händler Wertpapiere vergleichen muss, ist deren Volumen nur am Rande interessant; die Frage ist üblicherweise der Form "wie viel kriege ich im Verhältnis zu dem raus, was ich reinstecke?", weswegen nahezu alles in Prozent ausgewiesen wird.

    Und da sind 15 Stellen Genauigkeit mehr als ausreichend, zumal vieles eh Ansichts- oder Konventionssache ist. In der Praxis kuckt eh selten einer hinter die vierte Nachkommastelle, wenn es nicht um gesetzlich/vertraglich festgelegte Dinge wie etwa Stückzinsen geht, 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 deckt sich auch mit dem, was SeppJ schreibt und dem ich nur von Herzen zustimmen kann.



  • 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 🙂


Anmelden zum Antworten