dumme frage...



  • in der hoffnung, dass ich da nur nen dummen fehler gemacht hab, den ich - warum auch immer - nicht sehe:

    if((Differenz==0,11)||(Differenz==0,33)||(Differenz==0,55)||(Differenz==0,77)||(Differenz==0,99))

    aus irgend einem grund wird die bedingung immer als wahr angesehen. was mach ich falsch? (Differenz = floatVariable)



  • 🙄 🙄 wirklich dumme frage 🙄 🙄

    asm.a4s65d1a + as4d6a = dh1, mov:
    A
    


  • Ich sehe den Fehler nicht, hab auch keine Ahnung was mein Vorposter der Welt mitteilen wollte..

    Und du bist wirklich sicher, dass die Variable vorher nicht einen dieser Werte annimmt?



  • Ist das nicht Teil vom BWINF?



  • for(int i=0; i<AnzahlPreise; i++)
      {
        int AnzahlMoeglich;
        AnzahlMoeglich = 0;
        for(int u=0; u<AnzahlPreise; u++)
        {
          if(i!=u) 
          {
            float Summe, Differenz = 0;
            int Integer = 0;              
    
            Summe = Preise[i]+Preise[u];
            Integer = Preise[i]+Preise[u];
            Differenz = Summe - Integer;                                                                                                             
            if((Differenz==0,11)||(Differenz==0,33)||(Differenz==0,55)||(Differenz==0,77)||(Differenz==0,99))
            {
              Moeglich[i][u]=1; 
              AnzahlMoeglich++;
            }
          }
        Moeglich[i][i] = AnzahlMoeglich;       
        }
    
      }
    

    so mal im weiteren zusammenhang... tut mir leid, wenns irgendwas dummes ist - aber ich find einfach den fehler nicht (bin vielleicht müde ^^)



  • Wie wärs mit Debuggen?
    Im übrigen solltest du bei Gleitkommazahlen
    auf den Vergleich mit == verzichten.
    Da 2 gleiche Werte wegen Rundungsfehler
    ungleich erscheinen können!

    //EDIT:

    Differenz==0,11

    Komma?
    😕



  • Hallo

    Viel schlimmer ist aber das

    if (Differenz==0,11)
    

    immer wahr ist. Denn in C++ müßen Fließkommazahlen im Quellcode mit . angegeben werden. Der ,-Operator hingegen trennt ztwei einzelne Anweisung, so das 11 als einzelne Anweisung interpretiert wird und damit die Bedingung immer wahr ist.

    bis bald
    akari



  • geändert (also von komma auf punkt) ist kein wert mehr richtig (obwohl die zwischenergebnisse stimmen) - heißt das, dass der rundungsfehler immer auftaucht oder ist da noch irgendwas falsch?

    hmm... ich versteh die rechenweise des computers nicht.
    0.33 * 100 müsste 33 sein und das müsste doch problemlos in eine integerzahl konvertiert werden können. stattdessen zeigt er mir 32 an. bei 0.55 allerdings funktionierts.



  • Hallo

    Das Problem mit dem Rundungsfehler bekommst du nur in den Griff mit Vergleichen auf einen Bereich. Anstelle von

    if (Differenz == 0.11)
    

    must du eben schreiben

    if (Differenz > 0.109 && Differenz < 0.111)
    

    Das ganze läßt sich natürlich noch in Funktionen kapseln, bis hin zu Templates für verschiedene Genauigkeiten.

    hmm... ich versteh die rechenweise des computers nicht.
    0.33 * 100 müsste 33 sein und das müsste doch problemlos in eine integerzahl konvertiert werden können. stattdessen zeigt er mir 32 an. bei 0.55 allerdings funktionierts.

    Das was du da so einfach hinschreibst ist für den Computer recht schwer. Merk dir einfach : Die eingebauten Fließkommatypen float und double sind nicht exakt wie int. Das liegt auch nicht an C++ sondern der Prozessor rechnet so. Für Details siehe übliche Quellen zum Thema Fließkommazahlen.

    bis bald
    akari



  • Corin schrieb:

    geändert (also von komma auf punkt) ist kein wert mehr richtig (obwohl die zwischenergebnisse stimmen) - heißt das, dass der rundungsfehler immer auftaucht oder ist da noch irgendwas falsch?

    Da gibt's nicht nur Rundungsfehler, sondern die meisten Zahlen lassen sich logischerweise überhaupt gar nicht darstellen. Du musst also schauen ob der Betrag der Differenz kleiner als ein bestimmtes Epsilon ist um zu sehen ob die Zahlen "gleich" sind.



  • hmm...
    hab das mal wie folgt gemacht:

    Summe = Preise[i]+Preise[u];
            Integer = Preise[i]+Preise[u];
            Differenz = (Summe - Integer)*100;  
    
            Integer = int(Differenz+0.5);
    
            if((Integer==11)||(Integer==33)||(Integer==55)||(Integer==77)||(Integer==99))
    

    scheint zu funktionieren (hab noch nicht so viel zeit gehabt zu testen, aber auf anhieb mal bekommen, was erwartet) - ist das ein bekannter fehler oder kann man das vielleicht stehen lassen?



  • Hallo

    Das ist die übliche Art float in int zu runden (bei dir noch eine Verschiebung der Stellen). Dann funktionieren auch die Vergleiche im Rahmen der Genauigkeit. Du must dir natürlich im Klaren sein das Multiplizieren potentiell etwas ineffizienter ist als 2 Vergleiche.

    Und nochmal, das ist kein Fehlverhalten sondern technisch Bedingte Eigenschaften.

    bis bald
    akari



  • Der Fehler ist der dass du Geldbeträge (Preise[]) in floats/doubles speicherst und so damit rechnest. Das ist "asking for trouble".

    Geld rechnet man in Fixkomma, BCD, char[] oder sonstwas in der Richtung, aber niemals in float/double. Und mit "rechnen" meine ich *alles*, also von dem Moment wo du es aus einem File/einer Datebank/... ausliest bis zu dem Moment wo du es wieder ausgibst/abspeicherst/... . float/double haben dabei *nirgends* einen Platz.

    Warum? Ganz einfach wegen dem was du beobachtet hast. Das Konvertieren nach int funktioniert auch nicht zuverlässig, es könnte sein dass du bei einer Rechnung wo dezimal und auf Papier gerechnet 0,55 (55 als int) rauskommt du auf stattdessen 0,54 (54 als int) rausbekommst. Ganz grosses Kino. Lass das lieber.

    EDIT: genaugenommen funktioniert das Konvertieren nach Integer sehrwohl zuverlässig, die Fehler passieren schon vorher. Ändert aber ansonsten nichts daran was ich geschrieben habe.


Anmelden zum Antworten