Arithmetische Typenumwandlung



  • Kann mir einer erklären wie das genau geht?
    Also z.B. ;
    Zahl 1 = 2
    Zahl 2 = 1.2;

    Zahl 1 = int;
    Zahl 2 = double;

    Was passiert jetzt mit den beiden Zahlen?



  • Das nennt sich implizites Casten. Wenn du einen double-Wert einer int-Variable zuweist, dann werden einfach die Nachkommastellen abgeschnitten.

    Als Beispiel:

    int main()
    {
        double d = -7.3;
        int i = 3.2;
        int j = 4.9;
        int k = d;
    
        std::cout << i << std::endl; // Output 3
        std::cout << j << std::endl; // Output 4
        std::cout << k << std::endl; // Output -7
    }
    


  • Vielen Dank 🙂



  • Edit: Hat sich erledigt: D


  • Mod

    edit: Jetzt hast du die Frage wegeditiert, auf die ich geantwortet habe. 😞

    Da musst du aufpassen, da passieren mehrere Dinge gleichzeitig. Grundsaetzliche Regel: Einem Ausdruck ist es erst einmal grundsaetzlich egal, was spaeter mit ihm geschieht. Beispielsweise ist der rechten Seite eines Gleichheitszeichens vollkommen egal, was auf der linken Seite steht. Das heisst, hier wird zuerst i*ui ausgerechnet nach den dafuer vorgesehenen Regeln (siehe unten), dann wird bei Auswertung der Zuweisung das Ergebnis in den passenden Typ fuer die linke Seite umgewandelt. Ob auf der linken Seite vorher ein int, ein unsigned int, ein bool oder ganz was anderes (eigene Klassen koennen schliesslich auch einen Zuweisungsoperator haben) steht, ist bei der ersten Rechnung vollkommen egal.

    Wie werden nun gemischte arithmetische Typen miteinander verrechnet? Dazu gilt erst einmal die Regel, dass (fuer die eingebauten Datentypen) ein zweiseitiger Operator (also wie z.B. hier die Multiplikation) auf beiden Seiten den gleichen Typen haben muss. Ist dies nicht der Fall, so werden wieder implizite Umwandlungen vorgenommen, bis auf beiden Seiten der gleiche Typ steht. Dabei gelten grob folgende Regeln:
    -Es wird tendenziell zum groesseren (vom Wertebereich her) der beiden Typen hin umgewandelt (Beispiel: Operand 1 ist double, Operand 2 ist long double -> beide werden zu long double konvertiert, dann wird gerechnet, das Ergebnis ist dann auch long double)
    -Fliesskommazahlen gelten dabei als ob sie den groesseren Wertebereich haben (d.h. bei float und unsigned long long wird gerechnet, als waere beides float)
    -unsigned zaehlt hoeher als signed (Beispiel: Operand 1 ist int, Operand 2 ist unsigned int -> Rechnung und Ergebnis mit unsigned int)
    -Bei Typen kleiner als int werden beide als int behandelt (Beispiel: char, short und aehnliche).
    Eine genaue Liste steht im Standard am Anfang des Kapitels ueber Ausdruecke unter dem Stichwort "usual arithmetic conversions".

    Hier wird also i * ui im unsigned Zahlenraum ausgerechnet. Das Ergebnis ist ein unsigned int. Dieses wird dann im Rahmen der Zuweisung in einen int umgewandelt.
    Letztere Umwandlung ist "implementation-defined", wenn das Ergebnis nicht in einen int passt, aber bei den ueblichen Implementierungen kommt das heraus, was man erwartet:

    #include <iostream>
    int main()
    {
      unsigned i = 2;
      int j = -2;
      int k = i * j;
      std::cout <<  i*j << '\n' << k << '\n';
    }
    

    Ergibt praktisch ueberall

    4294967292
    -4
    

    oder ein vergleichbares Ergebnis. Hier sieht man auch, dass das Zwischenergebnis tatsaechlich unsigned ist.



  • Auch wenn ich die Frage wieder gelöscht habe (weil ich dachte das niemand antworten wird 😃 ) danke ich dir 🙂



  • Ich will nicht ständig ein neues Thema eröffnen deshalb frage ich mal in diesem 😃

    Muss ich als Anfänger ein Programm schreiben können das eine Sinus Kurve ausgibt? oder muss ich n kleines Spiel schreiben können? (mit nem ball etc.) in meinem Buch stehen nähmlich am Ende jedes Kapitels Aufgaben und die sind verdammt schwer und passen meistens nicht wirklich zum Thema....


  • Mod

    Talon schrieb:

    Muss ich als Anfänger ein Programm schreiben können das eine Sinus Kurve ausgibt? oder muss ich n kleines Spiel schreiben können? (mit nem ball etc.) in meinem Buch stehen nähmlich am Ende jedes Kapitels Aufgaben und die sind verdammt schwer und passen meistens nicht wirklich zum Thema....

    Wenn in deinem Buch ein einfaches Grafiksystem erklaert wird*, dann: Ja, die Aufgabe solltest du loesen koennen.
    Dein Buch ist Stroustrups "Programming principles and practice using c++", oder?

    *: Grafische Ausgabe ist eigentlich kein Kernbestandteil des C++-Kurrikulums.



  • Ne ich bin stolzer Besitzer des Buches: C++ Lernen und professionell anwenden

    Zum Beispiel werden im 4. Kapitel Schleifen erklärt,also was man mit ihnen machen kann usw.
    Wenn man dann zu den Aufgaben blättert, steht da dann z.B.

    Programmieren Sie folgendes Zahlenbeispiel:

    Der Computer merkt sich eine Zufallszahl zwischen 1 und 15, die der Spieler (=Benutzer) erraten soll. Der Spieler hat insgesamt drei Versuche. Nach jedem
    falschen Versuch gibt der Computer an, ob die angegebene Zahl zu klein oder zu groß ist. Ist auch der dritte Versuch erfolglos, wird die gesuchte Zahl ausgegegeben.

    Der Spieler hat gewonnen, wenn er spätestens beim dritten Versuch die Zahl errät.
    Er soll das Spiel beliebig oft wiederholen können.

    Zu Initalisierung des Zufallszahlengenerator verwenden Sie die Systemzeit. Die Funktion time() liefert die Anzahl Sekunden seit dem 1.1.1970, 0:0Uhr. Der
    long-Wert der Variable sek wird durch unsigned (sek) in einen unsigned-Wert
    umgewandekt und dann der funktion srand() übergeben.

    Davon verstehe ich nur die hälfte und die Lösung zu dieser Aufgabe ist noch
    komplizierter...
    Also die time() Funktion kam bisher nicht einmal vor....

    Das ist die Lösung:

    //  zahlenSp.cpp  :  Ein Zahlenspiel gegen den Computer 
    // ------------------------------------------------------------
    
    #include <cstdlib>      // Prototypen von srand() und rand()
    #include <ctime>        // Prototyp von time() 
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int  zahl, versuch; 
        char wb = 'w';           // wiederholen oder beenden
        time_t sek;
    
        time( &sek);             // Zeit in Sekunden lesen 
        srand((unsigned)sek);    // Zufallsgenerator initialisieren
    
        cout << "\n\n          "
             << " *******    EIN  ZAHLENSPIEL    *******" << endl;
    
        cout << "\n\nDie Spielregeln:" << endl;
    
        while( wb == 'w')
        {
           cout << "Ich merke mir eine Zahl zwischen 1 und 15\n"
                << "Sie haben drei Versuche die Zahl zu raten!\n"
                << endl;
    
           zahl = (rand() % 15) + 1;
    
           bool gefunden = false;
           int count = 0;
           while( !gefunden  && count < 3 )
           {
              cin.sync();              // Eigabepuffer löschen 
              cin.clear();
              cout << ++count << ". Versuch:   ";
              cin >> versuch;
    
              if( versuch < zahl)      cout << "zu klein!" << endl;
              else if( versuch > zahl) cout << "zu gross!" << endl;
              else                     gefunden = true;
           }
    
           if( !gefunden)
             cout << "\nIch habe gewonnen!"
                  << " Die gesuchte Zahl: " << zahl << endl;
           else
             cout << "\nBravo! Sie haben gewonnen!" << endl;
    
           cout << "Wiederholen --> <w>    Beenden --> <b>" << endl;
           do
             cin.get(wb);
           while( wb != 'w' &&  wb != 'b');
        }
        return 0;  
    }
    

  • Mod

    Die Zeilen 35 und 36 sind totaler Quark, aber ansonsten: Findest du das wirklich schwer? Das mit der Initialisierung des Zufallsgenerators ist etwas kompliziert ausgedrueckt. Haettest du aber die Grundfunktion auch nicht selber hin bekommen?



  • Doch naklar ich hab sogar das Programm alleine fertiggestellt nur dafür brauchte ich nen halben tag glaube ich (mit pausen) also ich verstehe es jetzt schon nur
    davor war es total schwer weil es im Buch noch nie erklärt wurde


  • Mod

    Schwer darf so eine Aufgabe ja auch durchaus sein. Du sollst ja was bei lernen. Unter anderem, wie man eine schier unloesbar erscheinende Problemstellung angeht. Wenn du selber auf die Loesung kommst, ist das ein gutes Zeichen.



  • Ist es eigentlich schlecht wenn man etwas googelt was man nicht verstanden hat?


  • Mod

    Talon schrieb:

    Ist es eigentlich schlecht wenn man etwas googelt was man nicht verstanden hat?

    Nein, im Gegenteil. Das ist, wie du spaeter ueberhaupt alles lernst, wenn du mal ueber die Anfaengerbuecher hinaus bist. Daher ist es gut, zu lernen, wie man gut googelt.

    Siehe auch die Linkliste fuer Neulinge hier im Forum. Insbesondere die dort angegebenen Referenzen sind sehr nuetzlich zur Selbsthilfe.



  • Welche Linkliste??



  • Talon schrieb:

    Welche Linkliste??

    Auf der ersten Seite von diesem Unterforum, ganz oben der erste Thread.
    Ist sogar als wichtig markiert.



  • Achsoo habe ich wohl übersehen danke



  • Talon schrieb:

    Achsoo habe ich wohl übersehen danke

    Das ist so gewollt.

    Das Wichtig: erzeugt ein PAL-Feld


Log in to reply