mit float Werten arbeiten (rechnen)



  • Hallöle !

    Ich hätte mal allgemein eine Frage zu float Werten.

    Bekanntlich kann der Rechner bestimmte Zahlen mit Nachkommastellen niemals genau darstellen. Wenn man z.B die Zahl 0.8 in Dualzahl umwandelt wird man festellen, daß es eine unendlich lange Zahl rauskommt. So kann der Rechner folglich solche Zahlen nur näherungsweise darstellen. z.B kann also passieren, daß der Rechner intern aus 0.8 eben 0.799999999 macht.

    Nun meine Frage ?

    Mein Programm nimmt vom Benutzer float Werte entgegen. Diese darf 0.8 oder aber auch 0.79 sein.

    Die Frage die sich dann für mich stellt ist : Wie kann ich solche - vom Rechner nur annäherungsweise darstellbaren Zahlen - am besten handhaben.
    Was ist, wenn ich die Werte haar genau so haben will wie vom Benutzer eingegeben, und NICHT nur näherungsweise.

    Denn wenn der Benutzer 0.8 eingibt, so muß ich auch die 0.8 haben und NICHT
    0.7999999999 ?!

    Ich habe echt keine Idee wie man mit soetwas umgehen könnte. Wenn ich z.B auf mein Konto 80.85 € habe dann möchte ich auch nicht, daß da irgendwie nach unten gerundet wird. Nach oben wäre schon O.K 🙂 .

    Für euere Ratschläge bin ich dankbar !!

    CIAO bolilein



  • Als String einlesen und in rationale Zahlen ('struct Rational { int zaehler, nenner; };') umwandeln?



  • Danke für den ersten Tipp !

    Es gefällt mir im Grunde schon recht gut, nur gibt es eine Funktion die den
    Ganz-zahl und den gebrochenen Teil zurückliefert ??

    Gut wäre auch, wenn ich den ganzzahl und die Nachkomma-stellen einfach als int Werte erhalten könnte. Ich habe schon im MSDN Libary gesucht aber bis jetzt noch nichts gefunden.

    Hat schon jemand mit soetwas zu tun gehabt; oder vielleicht noch ein Tipp oder Idee ??

    Vielen Dank an alle Beiträge !

    Gruß bolilein



  • ich hab bei uhrzeiten ints benutzt !



  • SORRY 1ntrud0r, aber ich verstehe nicht wie du dein Tipp meinst.

    Du sagst du hättest bei Uhrzeit ints benutzt und gibst noch diese Zeile an:
    (LOOP (FORMAT T "~%Burn in Hell"))

    Die Zeile sagt mir garnichts .

    Danke trotzdem

    bolilein



  • Das nennt sich Signatur, sowas kann man sich unter "Mein Profil" einstellen. Mir sagt die Zeile zwar was, ich wundere mich allerdings was intrud0r damit aussagen will.



  • Die Ganzzahl bekommst du so:

    int gzz = int(fliess);
    

    Die Nachkommastellen so:

    int nks = int(fliess - ganz * pow(stellen, 10));
    

    Dürfte eigentlich funzen



  • Vielleicht versuche ich nochmal meine Frage/Problematik neu darzustellen.

    Ich programmiere eine Koordinatensystem, welche nur den von Benutzer vorgegebenen Bereich darstellt. Daß heißt: Wenn der Benutzer vorgibt, daß die
    y-Achse von 0.34 bis 0.87 'gehen' soll mit einem Delta von 0.05, dann stellt sich die y-Achse dementsprechend ein.
    Hierzu muß ich natürlich einige vernünftige Anfangs und Endwerte finden. Deshalb habe ich einige Schleifen, wo Abbruchbedingungen mit
    Operationen wie < > == != usw. vorhanden sind!
    Gerade diese Operationen funktionieren aber mit float Werten nicht zuverlässig!! Man sagt auch: Vergleiche NIE 2 float Werte !!

    😕
    Deshalb meine Frage : Wie kann ich float-Werte am besten handhaben ??
    Was ist zu tun, wenn man in seinen Progi
    Vergleichsoperationen hat ??

    Ich dachte schon daran alles in Ganze-Zahlen umzuwandeln. Mein Betreuer war davon aber nicht begeistert.

    Viele Grüße an alle Programmers !! bolilein



  • entweder du definierst dir ein epsilon fuer das gleichheit gilt, also
    const double epsilon = 0.001;
    double d = 0.8;
    double d2 = irgendwas;

    if ( abs( d - d2 ) < epsilon )
    zahlen gleich
    else
    zahlen ungleich

    oder du rechnest gleich mit ganzzahlen.



  • Danke danke !

    😃
    Gefällt mir!! Ich möchte sowieso höchstens 3 Stellen hinter den Komma berücksichtigen.

    Ich glaube DAS bringt mich weiter!!

    CIAO und bis zu nächste Frage bolilein



  • 😉 Ja da bin ich wieder. :p

    Was jetzt anliegt ist klar.

    Wenn ich in meine Schleifen float-Werte aufsummiere,so fange ich mir auch immer mehr Fehler ein.
    Das heißt irgendwann überschreiten meine Rechnungen durchaus den definierten

    const double epsilon = 0.001;
    Und so kann ich wieder nicht vernünftig auf Gleichheit prüfen.

    Nun bin ich ratlos, wie ich mit sowas fertig werde ?!

    Soll ich versuchen lange Summationen zu vermeiden ??
    Ich denke das kann es nicht sein.
    Muß ich je nach Zahlenbereich(sprich je nach geforderten Genauigkeit) unterschiedliche Epsilon festlegen?
    Das kann es doch auch nicht sein.

    Hoffe entelechie, daß du mir wieder einen guten Tipp hast.

    Danke dir/euch Grüzzi von bolilein



  • Wenn Du wirklich hohe Genauigkeit brauchst kannste als allererstes mal auf double umstellen. Für 3 Stellen nach dem Komma sollte das eigentlich lagen.
    leider ist es tatsächlich so, daß die Genauigkeit je nach Rechenoperation schwankt. Besonders große und besonders kleine Zahlen zu addieren ist nicht wirklich günstig.
    Aber wenn Du Dein Koordinatensystem in einem vernünftigen Bereich (sagen wir +-100, 3 Nachkommastellen) bearbeitest sollten doubles eigentlich nahezu jeder Rechenoperation standhalten. Ansonsten mußte halt wirklich auf Brüche umsteigen.

    Achja, mit der Ganzzahl / Nachkommazahl ist natürlich nicht so geschickt, weil Du da genau wieder das Problem hast, daß Du periodische Zahlen nicht darstellen kannst.



  • 😕 Oh jeh !

    Das wird dann interessant sein.
    Der X-Achse soll nämlich Frequenzen darstellen und da gibt es durchaus hohe Werte.Also 1000 Einheiten für die X-Achse muß ich mindestens haben, selbst wenn ich dann die Achse, wenn hohe Werte vorliegen jeweils mit Kilo Mega und Giga (Terra) beschrifte. Denn zwischen diese Werten liegt ja bekanntlich immer der Faktor 1000.

    Ich probier weiter.

    Jester sagte vorhin, die Addition wäre kritisch bei zu kleinen oder zu großen Werten. Wie ist das mit der Multiplikation ?? Ist da auch derselbe Effekt ??

    Bin wirklich überrascht 😮 wieviele Probleme das Rechnen mit float Werten macht! Es muß aber irgendwie doch gehen! Bin ja nicht der erste der ein Koordinatensystem programmiert.

    Für Tipps jeder Art , weiterhin Vielen Dank 😉 bolilein



  • Nein, nicht die Addition von zu kleinen/zu großen Werten ist kritisch (okay, allzu groß/klein dürfen sie auch nicht sein), insbesondere die Addition einer sehr kleinen Zahl zu einer sehr großen (und umgekehrt ist kritisch).

    Wenn Du große Zahlen mit vielen Nachkommatstellen hast, dann ist auch die Multiplikation kritisch, überhaupt viele Nachkommastellen kann kritisch werden.
    An Deiner Stelle würd ich's aber einfach mal mit double probieren,

    und twar so:

    typedef double ValueType;

    und dann nur mit ValueType arbeiten. Dann testest Du, ob es Deinen Anforderungen genügt, falls nicht kannste mal gegen long double oder ne Rational-Klasse tauschen, oder sogar noch was anderes, aber es ist gut möglich, daß Dir doubles vollkommen ausreichen.



  • 🙂 Halllooo 😉

    Ich wollte mich nur nochmal bedanken !!

    Bis jetzt funktioniert es mit double Werten GUT !

    CIAO bis zur nächsten Frage bolilein



  • Original erstellt von Jester:
    Für 3 Stellen nach dem Komma sollte das eigentlich lagen.

    Ne, für 3 Stellen würde ich eher ein long double nehmen 😃 😉


Anmelden zum Antworten