Wie runde ich in C?



  • __-- 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.



  • HighLigerBiMBam schrieb:

    Wenn du weitere von mir unbekannte Unterschiede kennst, dann nenne sie und sage nicht nur "nein".

    cmath steht im Standard. math.h gibts bei dir nur, weils dein Compiler gut mit dir meint.


  • Mod

    Michael E. schrieb:

    HighLigerBiMBam schrieb:

    Wenn du weitere von mir unbekannte Unterschiede kennst, dann nenne sie und sage nicht nur "nein".

    cmath steht im Standard. math.h gibts bei dir nur, weils dein Compiler gut mit dir meint.

    Oder weil er auch einen C Compiler installiert hat (die beiden kommen ja meistens im Doppelpack) und diese sich ein Includeverzeichnis teilen.



  • Auch wenn man das von einigen Compiler-Funktionen (vorhanden ja/nein?) machen kann, stelle ich einmal eine seit langem dafür eingesetzte allgemeine Funktion runden() bereit. Diese findet sich auf meiner HP unter http://berniebutt.npage.de unter Programmieren -> Downloads.



  • berniebutt schrieb:

    Auch wenn man das von einigen Compiler-Funktionen (vorhanden ja/nein?) machen kann, stelle ich einmal eine seit langem dafür eingesetzte allgemeine Funktion runden() bereit. Diese findet sich auf meiner HP unter http://berniebutt.npage.de unter Programmieren -> Downloads.

    Ich kann nur vor diesem Code warnen.

    // Runden         06.11.2010													// Dann gilt die Ausrede "war früher so" schonmal nicht
    #include <iomanip.h>															// gibts nicht, brauchst du auch nicht
    #include <iostream.h>															// gibts nicht, brauchst du auch nicht außer für deine Debug-Ausgabe
    #include <fstream.h>															// gibts nicht, brauchst du auch nicht
    #include <stdlib.h>																// Ach, es soll C sein. Dann gibts die vorherigen drei Header erst recht nicht.
    
    void Runden(DOUBLE von,DOUBLE *nach,int nk)										// Warum nicht als Return-Wert? Warum Zeiger?
    //   --------------------------------------------------------------------------
    //   Fliesskommazahl (double) runden
    //   --------------------------------------------------------------------------
    //   von        übergebene Fliesskommazahl
    //   *nach      Zeiger auf gerundete Fliesskommazahl
    //   nk         Anzahl der Nachkommastellen										// Warum signed?
    //   test       Stream für Kontrollausdrucke (extern festgelegt, z.B. auf eine
    //              Datei)
    //   Rückgabe:  keine. Wer will, kann hier die Anzahl der digits (Vor- und
    //              Nachkommastellen) zurück liefern.
    //   --------------------------------------------------------------------------
    //   DOUBLE     mit #define festgelegter Typ (double oder long double)			// wunderschön
    //   Achtung:   Die Anzahl der möglichen Stellen (digits) richtet sich vor
    //              allem nach der Anzahl der Vorkommastellen. Diese ist durch den
    //              zwischenzeitlich benutzten Typ long int begrenzt auf 8, max 9.
    //              Bei Werten über einer Mrd ist die darstellbare Genauigkeit
    //              überschritten!													// WTF? Absolut unnötige Einschränkung, die durch deine komische Berechnung kommt. Desweiteren stimmt deine Berechnung nur für 32-bit-long, also z. B. nicht auf nem 64-Bit-Linux.
    //   --------------------------------------------------------------------------
    {
         long int   lvon;
         int        irest,i,faktor,minus=0;
         int        digits;
         DOUBLE     wert,rest,ziel;
         char       str[10];														// hier gibts dann nen schönen Überlauf bei 64-Bit-long
    //   test << "--> Runden - von-nk  "  << von << "  " << nk << endl;				// Streams? Eindeutig C++.
    //   ... positiver oder negativer Wert? ...
         wert = von;
         if(wert < 0.00)
         {
            minus = 1;
            wert = fabsl(wert);														// fabsl gibts in C++ nicht => eindeutig C
         }
    //   test << "... wert    " << wert << endl;
    //   ... Genauigkeitsbereich prüfen ...
    //   if(wert > 1000000000.)  // 1 Mrd											// Tolle Condition: selbst bei 32 Bits kannst du die Schranke mehr als verdoppeln. Aber ist ja nur ne Debug-Ausgabe...
    //   {
    //      test << "... Genauigkeitsbereich überschritten!" << endl;
    //      ... die Grösse wert müsste jetzt in 2 Teile aufgeteilt werden, die
    //          dann einzeln zu interpretieren sind ...
    //   }
    //   ... Nachkommastelen sind verlangt ...
         if(nk)																		// if(nk > 0), da nk signed
         {
            faktor = 1;
            for(i=0;i<nk;i++) faktor *=10;
            lvon  = (long int) wert;												// absolut unnötig, hier Ganzzahlen zu verwenden
            ltoa(lvon,str,10);														// nochmal absolut unnötig, hier ein char-Array zu verwenden, das dabei noch viel zu klein ist; achja, ltoa gibts in C++ nicht
            digits = strlen(str);
            rest  = wert - (DOUBLE)lvon + 0.5/faktor;  // Rundung in nk+1
            irest = rest * faktor;
            ziel = (DOUBLE)lvon + (DOUBLE)(irest) / faktor;
    //      test << "... faktor    " << faktor << endl;
    //      test << "... lvon      " << lvon << endl;
    //      test << "... str      :" << str << ":  " << digits << endl;
    //      test << "... rest      " << rest << endl;
    //      test << "... irest     " << irest << endl;
         }
    //   ... keine Nachkommastellen verlangt ...
         else
         {
            lvon  = (long int) wert;
            ziel = lvon;
         }
    //   ... gerundetes Ergebnis ...
         if(minus) ziel = -ziel;
         *nach = ziel;
    //   test << "--> Runden exit - ziel  " << setprecision(nk) << ziel << endl;
         return;
    }
    

    Bei der weiteren Berechnung hatte ich keine Lust mehr, mir zu überlegen, was da alles wegen der Fließkommaeigenschaften schiefgehen kann.

    Was soll überhaupt der ganze Code? Was spricht gegen sowas? Ist standardkonform und klappt sogar bei Zahlen > 1E10 🙄

    #include <cmath>
    
    double round(double value, unsigned int decPlaces)
    {
    	double factor = std::pow(10.0, static_cast<double>(decPlaces));
    	return std::floor(value * factor + 0.5) / factor;
    }
    


  • Übrigens: Wenn ich decPlaces bei mir signed mache, kann ich sogar auf Stellen vor dem Komma runden. Dein Parameter ist zwar signed, aber für alle negativen Eingaben verhält es sich so, als ob 0 übergeben worden wäre.


Anmelden zum Antworten