Wie runde ich in C?



  • Hey Leute!

    Ich stehe vor folgendem Problem:

    Nach einer bestimmten Berechnung bekomme ich entweder eine glatte ganze Zahl (z.B. 2), eine Zahl mit einer Nachkommastelle (z.B. 2,4), eine Zahl mit zwei Nachkommastellen (z.B. 2,42) oder eine Zahl mit drei Nachkommastellen (z.B. 2,423). Nun möchte ich das mein Programm erkennt, dass es mir nur Zahlen rundet die eine Nachkomastelle größer 2 hat. Hier geht es quasi um kaufmännisches Runden. Eine und zwei Nachkommstellen sind da ja erlaubt weil diese ganze Cent-Beträge darstellen, aber eben keine Nachkommstellen größer zwei Nachkommastellen.

    Könnt ihr mir helfen mein Problem zu lösen? Ich weiß nämlich da grad gar nicht weiter!

    Danke!



  • Nunja, mein erster Vorschlag wäre den Betrag einfach in Cent auszudrücken, damit wäre das 1. Problem gelöst.

    Das runden an sich könnte man

    float i = 5.55;
    i = (int)(i + 0.5);
    

    So lösen, nur so eine Idee..



  • Mein Verkaufsbetrag ergibt sich aber aus dieser Rechnung:

    int anzahl;

    erg = anzahl * 0.8 * 0.97

    Und da kann es eben abhängig von der "anzahl" dazu kommen, das ich einmal zwei Nachkommastellen oder das andere mal 3 Nachkommastellen entstehen können...

    Von daher müsste ich quasi flexibel unterscheiden wann ich runden muss und wann nicht...


  • Mod

    Siehe den Tipp, gar nicht erst Fließkommazahlen zu benutzen. Fließkommazahlen sind der falsche Typ um mit gequantelten Größen wie Geld zu rechnen.



  • Geld nie nie nie als Fliesskommazahl speichern.

    Denn die Daten werden binaer gespeichert und da tut man sich schwer mit den nachkommastellen.

    Stell dir das etwa so vor: Wenn ich 1/3 (ein drittel) habe, dann kann man das in der dezimalschreibweise nicht korrekt ausdruecken: 0,3333 trifft es ja nicht ganz. Man verliert also genauigkeit.

    Genauso geht es dir bei float und double. 0,7 ist uU nicht genau darstellbar und wird als 0,69999999999999999999997541290 gespeichert. Das kann sich natuerlich langsam zu rundungsfehlern aufsummieren...

    Deshalb speichere einfach das geld in cent. Dann hast du immer ganze Zahlen und hast dein Rundungsproblem mitgeloest.

    Wenn du unbedingt runden willst:
    Einfach mit 100 multiplizieren (um das komma zu verschieben) und dann wie cooky451 gesagt hat 0.5 addieren und auf int casten. Dann wieder durch 100 dividieren (um das komma wieder an die richtige stelle zu schieben).

    Aber wie gesagt: nimm lieber ganze Zahlen in cent. Ist viel einfacher und vorallem auch korrekter.



  • Shade Of Mine schrieb:

    Aber wie gesagt: nimm lieber ganze Zahlen in cent. Ist viel einfacher und vorallem auch korrekter.

    so ein quatsch hab ich ja schon lang nicht mehr gehört 😮



  • __-- schrieb:

    Shade Of Mine schrieb:

    Aber wie gesagt: nimm lieber ganze Zahlen in cent. Ist viel einfacher und vorallem auch korrekter.

    so ein quatsch hab ich ja schon lang nicht mehr gehört 😮

    Troll dich.



  • Hi Leute!

    Wie stellt ihr euch denn das vor, wie ich mit Cent-Beträgen rechnen soll? Meine Rechnung lautet ja: anzahl * 0.8 * 0.97. Das 0.8 stellt den Grundpreis dar, nämlich 0.8€ bzw. 80 Cent. Das 0.97 stellt einen Prozentsatz dar, der gewährt wird, wenn eine bestimmte Anzahl gekauft wird.

    Wie soll ich das jetzt mit Cent rechnen?

    So: anzahl * 80 * 0.97 Aber, dann bekomm ich ja wieder einen float raus, weil ich ja mit 0.97 addiere...

    Könnt ihr mir weiterhelfen?



  • bandchef schrieb:

    So: anzahl * 80 * 0.97 Aber, dann bekomm ich ja wieder einen float raus, weil ich ja mit 0.97 addiere...

    Könnt ihr mir weiterhelfen?

    Zum Beispiel:

    double Ergebnis = 80 * 0.97; //in Cent
    int gerundet = (int)(Ergebnis + 0.5); //in Cent
    

  • Mod

    Oder auch so:
    80 * 97 / 100



  • Hey Leute!

    Ich hab mich jetzt über mein Problem nochmal selber drüber gemacht und dabei folgendes erdacht:

    #include<iostream>
    using namespace std;
    
    int anzahl, b, c, d, e, f, g;
    
    int main(){
    cout << "Anzahl eingaben: ";
    cin >> anzahl;
    
    b = anzahl * 80 * 97;
    cout << "b = " << b << endl;
    
    c = b % 1000;
    //cout << c << endl;
    
    d = c / 10;
    //cout << d << endl;
    
    e = d % 10;
    //cout << e << endl;
    
    if(e >= 5)
    {
         f = (b / 100) + 1;
         cout << (float)f / 100;
         }
    else
    {
         cout << anzahl * 0.8 * 0.97;
         }
    
    system("pause");
    return 0;
    }
    

    Das Problem dabei ist jetzt allerdings, dass ab "Anzahl > 100000" die Rundung noch funktioniert aber nur noch auf eine Stelle gerundet wird.

    Wenn "Anzahl > 1000000" wird, dann hab ich gar keine Nachkommastelle mehr...

    Wie könnte ich dieses Problem noch in Griff bekommen?

    Könnt ihr mir helfen?



  • 1. Du bist im falschen Forum, du programmierst c++

    2. Warum machst du nicht: Wert = Wert - Wert % 100 ? (einfaches Runden)



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (C89 und C99) in das Forum C++ (auch C++0x) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Das was du schreibst entspricht ja nicht dem was ich will... oder?



  • dein programm ist etwas wirr (variablen-bezeichner, ...)

    #include <iostream>
    
    const unsigned int bestimmte_anzahl_ab_der_es_rabatt_gibt = 50;
    
    int main()
    {
      using namespace std;
    
      unsigned int anzahl;
      cin >> anzahl;
    
      unsigned int preis_pro_stk_in_cent = 80;
      unsigned int preis_in_cent = preis_pro_stk_in_cent * anzahl;
    
      unsigned int preis_nach_rabatt;
      if(anzahl >= bestimmte_anzahl_ab_der_es_rabatt_gibt)
      {
        preis_nach_rabatt = preis_in_cent*97 /100;
      }
      else
        preis_nach_rabatt = preis_in_cnet;
    
      cout << preis_nach_rabatt << endl;
    }
    

    das sollte so weit verständlich sein - jz noch das rabatt-gedöns in ne extra funktion und die variablen-name nicht so blöd nennen. dachte nur, dass es so vll leichter für dich zu verstehen ist 😉

    also:

    unsigned int preis_nach_rabatt(unsigned int preis, unsigned int anzahl)
    {
      const unsigned int grenze = 50;
    
      if(anzahl < grenze)
        return preis;
    
      preis *=  97;
      preis /= 100;
    
      return preis;
    }
    
    #include <iostream>
    
    int main()
    {
      using namespace std;
    
      unsigned int anzahl;
      cin >> anzahl;
    
      unsigned int stk_preis = 80;
      unsigned int preis_vor_rabatt = anzahl * stk_preis;
    
      unsigned int preis = preis_nach_rabatt(preis_vor_rabatt, anzahl);
    
      cout << preis << endl;
    }
    

    jetzt könnten wir noch 2 typedefs einführen:
    typedef unsigned int anzahl_type;
    und
    typedef unsigned int preis_type;

    wenn wir wollen können wir dann den anzahl-typ auch mal größer werden lassen und statt des unigned ints eine eigene kleine klasse für den preis nehmen, aber das wäre dann wohl zu viel 😉

    bb

    PS: Natürlich kannst du auch float nehmen - aber wenn du den hier verlinkten Thread mal bis auf Seite 4-5 gelesen hast, hast du ja gesehen, dass das (fast^^) unendlich viele Nachteile mit sich bringt.
    http://www.cplusplus.com/reference/clibrary/cmath/
    hier sind auch alle funktionen aufgelistet, die dir Standard-C++ im Mathematik-Bereich bietet.



  • #include <iostream>
    #include <iomanip>
    #include <math.h>
    
    using namespace std;
    
    double Round(double Zahl, int Stellen) 
    { 
        return floor(Zahl * pow((double)10, Stellen) + 0.5) * pow((double)10, -Stellen); 
    }
    
    int main()
    {
    	double d = 0;
    
    	cout << "Geben einen Wert ein: ";
    	cin >> d;
    
    	d = Round(d, 2);
    
    	cout << fixed << setprecision(10) << d;
    
    	cin.get();
    	cin.get();
    
    	return 0;
    }
    

    Viel spaß (ps: steht im C forum FAQ)



  • _das_ steht in der faq? OO

    //#include <math.h> -- gibts nicht mehr
    #include <cmath>
    
    //(double)10 -- zwar nicht falsch, aber man kanns auch noch umständlicher machen... ich schreib doch auch nicht (int)10.0 wenn ich 10 brauche...
    10.
    //oder
    10.0
    

    bb



  • unskilled schrieb:

    _das_ steht in der faq? OO

    //#include <math.h> -- gibts nicht mehr
    #include <cmath>
    
    //(double)10 -- zwar nicht falsch, aber man kanns auch noch umständlicher machen... ich schreib doch auch nicht (int)10.0 wenn ich 10 brauche...
    10.
    //oder
    10.0
    

    bb

    A. Es steht in der FAQ von C genau so.
    B. math.h includiert cmath in c++, seine Frage war aber: "Wie rundet man in C"
    C. Mit dem 10. oder 10.0 gebe ich dir recht.

    😃



  • HighLigerBiMBam schrieb:

    B. math.h includiert cmath in c++

    Nein.

    HighLigerBiMBam schrieb:

    seine Frage war aber: "Wie rundet man in C"

    Trotzdem darf man auch auf andere Dinge hinweisen.


  • Mod

    HighLigerBiMBam schrieb:

    seine Frage war aber: "Wie rundet man in C"

    Er weiß bloß nicht, dass er C++ macht. Sein erstes Codebeispiel hat dies aber deutlich gemacht.



  • math.h oder cmath total egal! Mit dem winzigen Unterschied, das cmath im namespace std liegt. Klasse das bringts echt wenn ich using namespace std mache!

    Ist wie die Frage: "Was ist besser Gauda oder Mortadella?" Käse ist und bleibt Käse.

    Die Tatsache das cmath in c++ beliebter ist heißt nicht dass man da jedesmal drauf rumreiten muss. Wenn du weitere von mir unbekannte Unterschiede kennst, dann nenne sie und sage nicht nur "nein".

    Seppel schrieb:
    seine Frage war aber: "Wie rundet man in C"
    Er weiß bloß nicht, dass er C++ macht. Sein erstes Codebeispiel hat dies aber deutlich gemacht.

    Ja ich weiß siehe Thread vor verschieben.


Anmelden zum Antworten