Rudnungsproblem mit double



  • Hi,
    hab ein kleines Rundungsproblem bei meinem Programm und zwar:
    ich rechne die ganze Zeit meine double Variable plus und minus einer anderen Double und nach ungefähr 400,000 rechnungen rundet er schon ein 0.000001 drauf und so weiter.
    ich brauch aber ne ganz genaue Zahl und int geht leider auch nicht weil die zahl zu groß für ein int wird.

    wer cool wenn ihr ne idee habt wie ich das verhindern kann.

    thx 😉



  • FabianKelschotz schrieb:

    ich brauch aber ne ganz genaue Zahl und int geht leider auch nicht weil die zahl zu groß für ein int wird.

    Geht long long als Typ?


  • Mod

    Wenn du sagst, dass die Zahlen zu groß sind für Integer, dann wundert mich, dass du dich über einen Fehler von 0.000001 aufregst. Das ist was, die 15. zählende Stelle? Guck dir mal an, wie Fließkommazahlen funktionieren, du machst nämlich etwas entschiedendes falsch, wenn du mit solchen Zahlenmodellen ein 100% exaktes Ergebnis möchtest, Fließkommazahlen sind für andere Anwendungen.

    Wenn das exakte Ergebnis so wichtig ist und es sich nur um Rechnungen mit Ganzzahlen handelt, such mal bei Google nach BigInt. Falls es rationale Zahlen sind, gibt es auch fertige Bibliotheken zur Bruchrechnung. Falls es ganz allgemeine reelle Zahlen sind, bist du auf einem Computer mit endlichen Speicher aufgeschmissen, das sollte dir klar sein. Dann kannst du nur die Genauigkeit immer weiter erhöhen (long double...) oder musst zu einem Programm greifen, das formell rechnet.



  • ne long long geht auch nicht und ein long alleine hilft auch nicht nur das es dann doppelt so viele rechnungen braucht 😞



  • Was willst Du erreichen?


  • Mod

    FabianKelschotz schrieb:

    und ein long alleine hilft auch nicht nur das es dann doppelt so viele rechnungen braucht 😞

    Magst du das erläutern? Das klingt irgendwie komisch.



  • Bau halt eine Klasse für Brüche mit den gängigen Operatoren?
    Dazu bin ich übergegangen, performancemäßig gar nicht mal so viel schlechter.



  • Danke für die Antworten.
    ich runde die Zahl jetzt einfach sobald es nicht mehr passt.
    ist zwar nicht schön erfüllt aber seinen Zweck


  • Mod

    FabianKelschotz schrieb:

    Danke für die Antworten.
    ich runde die Zahl jetzt einfach sobald es nicht mehr passt.
    ist zwar nicht schön erfüllt aber seinen Zweck

    Sicherlich die beste Lösung[/Ironie]



  • SeppJ schrieb:

    Fließkommazahlen sind für andere Anwendungen.

    Ich frage mich gerade, wofür Fließkommazahlen überhaupt gut sein sollen. Fast täglich kommen hier die Beschwerden, als Grund wird dann immer "dafür sind Fließkommazahlen nicht gedacht" angegeben.



  • SeppJ schrieb:

    Sicherlich die beste Lösung[/Ironie]

    Nicht ideal, aber hält mindestens 49,7 Tage lang.



  • 314159265358979 schrieb:

    SeppJ schrieb:

    Fließkommazahlen sind für andere Anwendungen.

    Ich frage mich gerade, wofür Fließkommazahlen überhaupt gut sein sollen. Fast täglich kommen hier die Beschwerden, als Grund wird dann immer "dafür sind Fließkommazahlen nicht gedacht" angegeben.

    ich benutze sie bei einem kleinem Spiel (pacman) um zu sehen ob die figur grade "grade" also mitten im pfad ist und somit die richtung ändern kann (also wenn x = irgenwas.00000 ist)

    @SeppJ
    wenn ich aus dem double ein long double mache braucht man doppelt soviele rechnungen bis man einen rundungsfehler sieht. 🙂

    @volkard
    hat nur 1,3 stunden lang gehalten 😡
    machs jetzt mit mehren ints


  • Mod

    314159265358979 schrieb:

    SeppJ schrieb:

    Fließkommazahlen sind für andere Anwendungen.

    Ich frage mich gerade, wofür Fließkommazahlen überhaupt gut sein sollen. Fast täglich kommen hier die Beschwerden, als Grund wird dann immer "dafür sind Fließkommazahlen nicht gedacht" angegeben.

    Da wo du im echten Leben mit reellen Zshlen rechnen würdest. Also so ziemlich sämtliche Physik, Chemie, Ingenieurskunst und mathematische Numerik.

    Man darf nur nicht denken, ein Komma in einer Zahl oder große Werte würden bedeuten, dass man Fließkomma braucht. Viele Anfänger verwechseln dies. Und da so viele Anfängeraufgaben sich um Geld drehen, kommen hier os oft solche Fragen.



  • FabianKelschotz schrieb:

    ich benutze sie bei einem kleinem Spiel (pacman) um zu sehen ob die figur grade "grade" also mitten im pfad ist und somit die richtung ändern kann (also wenn x = irgenwas.00000 ist)

    Was mit ints gar nicht geht.
    Oder ists bei ints: (also wenn x%1000==0). Wenn ja, kannste nur für den Geradheitstest beliebig oft 1024 zufügen uder wegmachen (, um rechtzeitig vor Überläufen zu intervenieren) oder gleich mit unsigned int (und %1024) rechnen und gar nichts machen.

    Wenn der int 1 Sekunde hält, und es nur ums Aufsummieren ähnlich kleiner Schritte geht, hält der long long 136 Jahre.



  • ich benutze die ints als hätten sie ein komma
    also wenn z.b (x*y*z % 100000 == 0) biegt der pacman ab
    das komma denke ich mir also bei der xten stelle



  • FabianKelschotz schrieb:

    ich benutze die ints als hätten sie ein komma
    also wenn z.b (x*y*z % 100000 == 0) biegt der pacman ab
    das komma denke ich mir also bei der xten stelle

    Ok. Mit Festkommazahlen haben wir viel Erfahrung.
    Wobei mir dann if(x*y*z % 100000 == 0) nicht klar ist und sich gar nicht gut vereinfachen läßt.
    Es ist nicht if(x%100==0 and y%100==0 and z%10==0).



  • volkard schrieb:

    FabianKelschotz schrieb:

    ich benutze die ints als hätten sie ein komma
    also wenn z.b (x*y*z % 100000 == 0) biegt der pacman ab
    das komma denke ich mir also bei der xten stelle

    Ok. Mit Festkommazahlen haben wir viel Erfahrung.
    Wobei mir dann if(x*y*z % 100000 == 0) nicht klar ist und sich gar nicht gut vereinfachen läßt.
    Es ist nicht if(x%100==0 and y%100==0 and z%10==0).

    IIRC gilt aber, dass wenn x*y*z % 100000 == 0 ist, dann ist auch x%100000 * y%100000 * z%100000 == 0.

    Was aber nicht soviel bringt, da die %-Operation eine größere Laufzeit braucht, als die *- und sogar die /-Operation.

    Der Modulo-Operator könnte etwa so implementiert sein:

    int operator%(int n, int p){
      return n - n / p * p;
    }
    

    Man muss jetzt aber hoffen, dass der Compiler nicht auf die Idee kommt, das /p*p zu *1 zu optimieren 🤡



  • Man kann schlauerweise auch %1024 rechnen statt %1000.


Log in to reply