Problem mit Variablen in einem einfachen Programm.



  • int/unsigned int



  • icarus2 schrieb:

    Du musst der Variable 'Brutto' einen Startwert geben, das heisst initialisieren. Ansonsten hat die Variable irgend einen (oftmals sehr merkwuerdigen) Wert. Deshalb bekommst du dann auch ein so merkwuerdiges Ergebnis.

    Jo danke 😃



  • benimus schrieb:

    SeppJ schrieb:

    Wie immer: float ist der ungeeignetste Datentyp für Geld. Die vermeintliche Ähnlichkeit ist rein optisch, logisch ist ein sehr großer Unterschied.

    Und welcher typ wäre passender? 😃

    Man sollte auf cent-Basis rechnen (nicht einlesen umbedingt). Macht bei Programmierergehaelten sowieso mehr sinn 😃

    std::size_t cent;// Ein typedef auf einen vorzeichenlosen Skalar, definiert in <cstring>
    float eur;
    std::cin >> eur;
    cent = eur * 100;
    

    Edit: Rechtschreibfehler korrigiert 🙄



  • ich hätte erwähnen sollen, dass ich ein blutiger anfänger bin 😃 bei so einem codebeispiel:

    std::size_t cent;// Ein typedef auf einen vorzeichenlosen Skalar, definiert in <cstring>
    float eur;
    std::cin >> eur;
    cent = eur * 100;
    

    saß ich so vor dem Rechner 😮 ok, das meiste habe ich verstanden aber "size_t" und "<cstring>" ist mir nicht geläufig :P... egal
    der überarbeitete Quellcode:

    #include <iostream>
    using namespace std;
    
    const int MwstSatz = 19;
    
    int main()
    {
    	unsigned int Netto;   
    	unsigned int Brutto;
    	unsigned int Steuer;
    
    	cout << "Geben sie einen (positiven) Nettobetrag in Cent ein: " << endl;
    	cin >> Netto;
    	Steuer = MwstSatz * Netto / 100;
    	Brutto = Netto + Steuer;
    	cout << "Der Bruttopreis betraegt (bei " << MwstSatz << "% Mwst): " << Brutto << endl;
    	cin >> Brutto;
    
    }
    

    funktioniert auch alles wie gewollt 😃



  • benimus schrieb:

    "size_t"

    Anfaenger? Ich formuliere es mal so: **Ist dasselbe wie unsigned int **

    benimus schrieb:

    und "<cstring>" ist mir nicht geläufig 😛

    #include <cstring>
    


  • Sone schrieb:

    benimus schrieb:

    "size_t"

    Anfaenger? Ich formuliere es mal so: **Ist dasselbe wie unsigned int **

    benimus schrieb:

    und "<cstring>" ist mir nicht geläufig 😛

    #include <cstring>
    

    size_t ist aus <cstddef>, nicht aus <cstring>



  • Sone schrieb:

    std::size_t cent;// Ein typedef auf einen vorzeichenlosen Skalar, definiert in <cstring>
    

    Wie kommst du denn bitte auf size_t für Geld?

    @benimus: cstring ist ein Header, der Deklarationen und Definitionen (hauptsächlich) zur Nutzung der Stringoperationen der C-Standardlibrary enthält. Unter anderem eben auch den Typ size_t. Dieser wird meist für Größenangaben von Speicherbereichen genutzt (z.B. eben bei memcpy aus cstring) und ist auch der Ergebnistyp des sizeof-Operators.

    Brauchst du hier aber imho alles nicht.



  • IrgendeinName schrieb:

    Sone schrieb:

    benimus schrieb:

    "size_t"

    Anfaenger? Ich formuliere es mal so: **Ist dasselbe wie unsigned int **

    benimus schrieb:

    und "<cstring>" ist mir nicht geläufig 😛

    #include <cstring>
    

    size_t ist aus <cstdlib>, nicht aus <cstring>

    Nein, es ist aus cstring!

    size_t ist ein Groessentyp. Die Anzahl von Cents ist eine Groesse. ➡ 💡

    Edit: Ausserdem braucht man <cstring> fuer size_t fast nie einzubinden, da das die meisten anderen Header schon machen...



  • IrgendeinName schrieb:

    size_t ist aus <cstdlib>, nicht aus <cstring>

    Zumindest meine POSIX-Manpage sagt dazu:

    The <string.h> header shall define the following:
    
           NULL   Null pointer constant.
    
           size_t As described in <stddef.h> .
    

    Bezweifle, dass sich C++ hier unterscheidet. Tatsächlich müssen aber sowohl stdlib.h, als auch string.h (neben stddef.h) den size_t-Typedef verfügbar machen.



  • Sone schrieb:

    benimus schrieb:

    "size_t"

    Anfaenger? Ich formuliere es mal so: **Ist dasselbe wie unsigned int **

    benimus schrieb:

    und "<cstring>" ist mir nicht geläufig 😛

    #include <cstring>
    

    ok, und das mit <cstring> war mir klar, ich weiß nur nicht, was das bewirkt :p



  • Wenn du Zeit hast, studiere folgenden Code (dein Code sollte so aussehen):

    #include <iostream>
    #include <limits>
    #include <iomanip>
    #include <complex>
    
    const float MwstSatz = 0.19;
    const size_t CentsInEur = 100;
    
    int main()
    {
        size_t Nettoct, Steuerct, Bruttoct;
    
        std::cout << "Geben sie einen Nettopreis ein: \n";
    
        {//Eingabe
            float ct;
            while(!(std::cin >> ct))
            {
                std::cout << "Bitte richtig machen, doedel!\n";
                std::cin.clear(); //Stream zuruecksetzen
                std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
            }
            Nettoct = ct * CentsInEur;
        }
    
        Steuerct = Nettoct * MwstSatz; // Muss das gepuffert werden... ?
        Bruttoct = Nettoct + Steuerct;
        float BruttoEur = static_cast<float>(Bruttoct) / CentsInEur;//Hier wird Brutto in Cent wieder in Euro umgewandelt
    
        std::cout << "Der Bruttopreis ist wiefolgt: " //Ausgabe
                  << std::setprecision(  std::log10(BruttoEur) + 1 + std::log10(CentsInEur) ) //Wir wollen 2 Nachkommastellen, also sagen wir das
                  << BruttoEur 
                  << '\n';
    
        std::cin.get();
    }
    

    http://ideone.com/88ZyA

    Wenn du besonders viel Zeit hast, bastele noch ein/zwei Klassen, die das alles koennen!

    Schoener gingen die globalen Konstanten natuerlich mit std::ratio .



  • Sone schrieb:

    Wenn du Zeit hast, studiere folgenden Code (dein Code sollte so aussehen):

    #include <iostream>
    #include <limits>
    #include <iomanip>
    #include <complex>
    
    const float MwstSatz = 0.19;
    const size_t CentsInEur = 100;
    
    int main()
    {
        size_t Nettoct, Steuerct, Bruttoct;
    
        std::cout << "Geben sie einen Nettopreis ein: \n";
    
        {//Eingabe
            float ct;
            while(!(std::cin >> ct))
            {
                std::cout << "Bitte richtig machen, doedel!\n";
                std::cin.clear(); //Stream zuruecksetzen
                std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
            }
            Nettoct = ct * CentsInEur;
        }
    
        Steuerct = Nettoct * MwstSatz; // Muss das gepuffert werden... ?
        Bruttoct = Nettoct + Steuerct;
        float BruttoEur = static_cast<float>(Bruttoct) / CentsInEur;//Hier wird Brutto in Cent wieder in Euro umgewandelt
    
        std::cout << "Der Bruttopreis ist wiefolgt: " //Ausgabe
                  << std::setprecision(  std::log10(BruttoEur) + 1 + std::log10(CentsInEur) ) //Wir wollen 2 Nachkommastellen, also sagen wir das
                  << BruttoEur 
                  << '\n';
    
        std::cin.get();
    }
    

    http://ideone.com/88ZyA

    Wenn du besonders viel Zeit hast, bastele noch ein/zwei Klassen, die das alles koennen!

    Schoener gingen die globalen Konstanten natuerlich mit std::ratio .

    öhm, danke... 😮



  • Ist zum lernen. Geh Zeile fuer Zeile durch und schlag in der Referenz nach. Bei Fragen, frag hier im Thread oder mach einen zweiten auf.

    Edit: Zeile 21 ist wirklich etwas kompliziert. Ueberspring die erstmal.



  • Sone schrieb:

    benimus schrieb:

    "size_t"

    Anfaenger? Ich formuliere es mal so: **Ist dasselbe wie unsigned int **

    Anfänger?
    Ja, du bist ein Anfänger. Deine Behauptung ist falsch. Dein inflationäres Geplapper spiegelt Anfängeraberglauben und naives Unverständnis bei Grundlagen zu C bzw. C++ wider.


  • Mod

    size_t wird in <cstio>, <cstdlib>, <cstring> und <ctime> deklariert.

    Sone schrieb:

    size_t ist ein Groessentyp. Die Anzahl von Cents ist eine Groesse. ➡ 💡

    Nicht jeder mit einer Erleuchtung ist auch ein Prophet. Die meisten sind bloss Spinner.

    Sone schrieb:

    Edit: Ausserdem braucht man <cstring> fuer size_t fast nie einzubinden, da das die meisten anderen Header schon machen...

    Keiner der anderen Standardheader bindet <cstring> ausdrücklich ein. Zudem ist "fast nie" gerade kein Grund, einen benötigten Header auszulassen.



  • Wutz schrieb:

    Deine Behauptung ist falsch.

    *lol*

    Folgendes steht in einem Standardheader von MinGW (GCC 4.6.2):

    #ifdef _WIN64//Ausnahme
    _    _MINGW_EXTENSION typedef unsigned __int64 size_t;
    #else
        typedef unsigned int size_t;
    #endif /* _WIN64 */
    

    Klar ist das im Standard nicht garantiert. Aber es einem Anfaenger so genau zu machen ist laecherlich unnoetig.

    size_t ist ein Groessentyp. Die Anzahl von Cents ist eine Groesse.

    Nicht jeder mit einer Erleuchtung ist auch ein Prophet. Die meisten sind bloss Spinner.

    Ich sehe nach wie vor kein Problem, fuer eine Anzahl size_t zu verwenden. Klar war meine Formulierung bescheuert. Trotzdem sehe ich kein Problem.

    Edit: Ausserdem braucht man <cstring> fuer size_t fast nie einzubinden, da das die meisten anderen Header schon machen...

    Keiner der anderen Standardheader bindet <cstring> ausdrücklich ein.

    Mit "das" meinte ich, size_t deklarieren. Edit: Jup, ich muss mich anders ausdruecken.
    Denn bspw. binde ich <iostream>, <string> o. ae. ein, ist size_t deklariert. Ich musste noch nie wegen size_t explizit einen deiner genannten Header einbinden.



  • Sone schrieb:

    Ich sehe nach wie vor kein Problem, fuer eine Anzahl size_t zu verwenden. Klar war meine Formulierung bescheuert. Trotzdem sehe ich kein Problem.

    Das Problem ist zum Beispiel, dass size_t nicht nur eine bestimmte Größe beschreibt, sondern die Größen von Speicherbereichen.


  • Mod

    Sone schrieb:

    Klar ist das im Standard nicht garantiert. Aber es einem Anfaenger so genau zu machen ist laecherlich unnoetig.

    Das eine ist korrekt, das andere nicht. Demnächst fängst du noch an, J.W. zu zitieren.

    Sone schrieb:

    camper schrieb:

    Sone schrieb:

    size_t ist ein Groessentyp. Die Anzahl von Cents ist eine Groesse.

    Nicht jeder mit einer Erleuchtung ist auch ein Prophet. Die meisten sind bloss Spinner.

    Ich sehe nach wie vor kein Problem, fuer eine Anzahl size_t zu verwenden. Klar war meine Formulierung bescheuert. Trotzdem sehe ich kein Problem.

    Das Problem fängt damit an, dass du die zu lösende Aufgabe nicht kennst. Was ist z.B. mit negativen Geldbeträgen? Je nach Aufgabenstellung ist so etwas sinnvoll oder eben auch nicht. Ein Warenpreis wird (m.E.) nie negativ sein, ein Kontostand ist das schon mal. Und überhaupt, bloss weil das Programm auf einem alten Rechner läuft, soll ich nicht mit hohen Millionbeträgen (in Euro) umgehen können?

    Sone schrieb:

    camper schrieb:

    Sone schrieb:

    Edit: Ausserdem braucht man <cstring> fuer size_t fast nie einzubinden, da das die meisten anderen Header schon machen...

    Keiner der anderen Standardheader bindet <cstring> ausdrücklich ein.

    Mit "das" meinte ich, size_t deklarieren. Edit: Jup, ich muss mich anders ausdruecken.
    Denn bspw. binde ich <iostream>, <string> o. ae. ein, ist size_t deklariert. Ich musste noch nie wegen size_t explizit einen deiner genannten Header einbinden.

    In diesem Forum geht es um C++, vorzugsweise solches, das auch noch standardkonform ist. Nicht um deine persönlichen Erfahrungen. Die können vielleicht Indiz, aber niemals Grund sein.
    Irgendwann werden die Header sicher auch noch in Bezug auf size_t aufgeräumt werden. Wäre ja z.B. kein Problem, intern einen anderen Bezeichner wie __size_t oder so zu verwenden.



  • [InGedanken]Haette ich bloss einfach int genommen, einfach int![/InGedanken]

    Ist ja gut.


  • Mod

    benimus schrieb:

    SeppJ schrieb:

    Wie immer: float ist der ungeeignetste Datentyp für Geld. Die vermeintliche Ähnlichkeit ist rein optisch, logisch ist ein sehr großer Unterschied.

    Und welcher typ wäre passender? 😃

    Nur zum Verständnis:
    Gleitkommawerte wie float und double bieten eine Genauigkeit, die von der absoluten Größe des dargestellten Wertes abhängt. D.h. der relative Fehler des Wertes ist (näherungsweise) konstant.
    Das macht diese Typen geeignet für wissenschaftlich-technische Berechnungen, denn dort arbeitet man für gewöhnlich mit Größen, die einen gewissen bekannten Fehler relativ zur ihrer Größe aufweisen.

    Finanzanwendungen sind da völlig anders: Geldbeträge sind in den allermeisten Fällen (wenn wir mal von Schätzwerten absehen) exakte (und diskrete) Größen. Und auch Rechenergebnisse (selbst wenn sie als Ergebnis eines Rundungsschrittes entstehen) sind exakt bzgl. dessen, was sie darstellen.
    Für derartige Berechnungen sind integrale Typen oder auch Festkommatypen, wie es sie in einigen Sprachen gibt, geeignet.
    Je nach Aufgabentyp wird man für gewöhnlich Rechnungen mit einer gewissen Grundeinheit durchführen, von der bekannt ist, dass hiervon keine Bruchteile auftreten können. Das können Euro sein, cent, vielleicht auch 1/100 cent (kennt man z.B. von Telefonkostenabrechnungen mit Einzelverbindungen) oder etwas anderes Aufgabenspezifisches.


Anmelden zum Antworten