Hilfe bei Aufgabe aus "Der C++ Programmierer"



  • Hallo

    Ich lerne gerade C++ mit dem Buch Der C++ Programmier von Ulrich Breymann.
    Leider habe ich schon bei der zweiten Aufgabe nicht verstanden was man genau machen muss.
    Kann mir das jemand genauer erklären ?

    Schreiben Sie ein Programm, das die grösstmögliche unsigned int Zahl(int, long, unsigned long) ausgibt, ohne dass die Kenntnis der systeminternen verwendeten Bitanzahl für jeden Datentyp benutzt wird. Hinweis: studieren Sie die möglichen Operatoren für ganze Zahlen und die Datei limits.h

    Das ist die Lösung:

    /* cppbuch/loesungen/k1/2.cpp
       Beispiel zum Buch von Ulrich Breymann: Der C++ Programmierer; Hanser Verlag
       Diese Software ist freie Software. Website zum Buch: http://www.cppbuch.de/ 
    */
    #include<iostream>
    using namespace std;
    
    int main() {
       unsigned int ui = 0;
       unsigned long int uli = 0;
       cout << "max. unsigned int     = "<< ~ui       << endl;
       cout << "max. unsigned long int= "<< ~uli      << endl;
       cout << "max. int              = "<< (~ui>>1)  << endl;
       cout << "max. long int         = "<< (~uli>>1) << endl;
    }
    

    Ich verstehe auch nicht genau was eine bitweise Negation ist.
    Es ist dieses Zeichen -> ~
    Im Buch wurde es nicht genau erklärt nur kurz angegeben.
    Die Lösung verstehe ich nur wenig. Vor allem das Zeichen ~ und ">> 1" nicht.
    Es wäre nett wenn mir jemand ein wenig helfen könnte.

    Vielen Dank



  • #include <bitset>
    #include <iostream>
    
    using std::cout;
    using std::bitset;
    
    int main()
    {
    
    	long int l = 0;
    	bitset<32> longset(l);
    	cout << longset.to_string() << '\n';
    	longset = ~longset;
    	cout << longset.to_string() << '\n';
    	cout << longset.to_ulong() << '\n';
    
    }
    

    Führ einmal dieses Programm aus. Es zeigt dir was der Operator ~ mit einer Zahl macht. (Normalerweise würde einen unsigned long nehmen, aber VC++ hat da einen Bug).

    Hier nochmal erklärt:
    Das ist eine Binärzahl:
    0000 0000 = 0 Dezimal.
    Wenn wir Bitweises-Nicht mit der Zahl machen, wird jede 0 zu eins und jede 1 zu 0.

    ~(0000 0000) = 1111 1111 = 255
    ~(1111 1111) = 0000 0000 = 0

    Der >> Operator shiftet Bits = verändert die Position.
    Wenn du eine signed (vorzeichenbehaftete) Zahl hast, wird das linkste (= erste Bit) der Zahl für den negativen Wert verwendet. Wenn du also den maximalen Wert haben willst, muss das erste Bit weg, nachdem du es bitwise geNOTet hast.
    Wenn du >> 1 auf 1111 1111 machst, wird es zu 0111 1111
    Wenn du >> 1 auf 0110 0000 machst, wird es zu 0011 0000



  • Vielen Dank !
    Ich glaube ich habe es jetzt verstanden.
    Aber wie krieg ich die grösstmögliche einer int raus ?

    So habe ich es versucht:

    int a = 0;
    a = (~a>>1);
    

    Da krieg ich -1.
    1111 1111 1111 1111 1111 1111 = -1



  • Ich muss eine 0 'reinschieben', deswegen kam immer 1111 1111 statt 0111 1111.
    Stimmt das so ?

    int a;
    a = (~a>>0)
    


  • Neuling._ schrieb:

    Aber wie krieg ich die grösstmögliche einer int raus ?

    z.B. so:

    int i = 1;
    = ~(i << (sizeof(int)*8-1));
    cout << "max. int = "<< i;
    

    An dieser Stelle kann man auch noch erwähnen, dass unsigned short int=0 negiert meist -1 liefert:

    A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion
    rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all
    the values of the source type.

    The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.

    The rank of a signed integer type shall be greater than the rank of any signed integer type with a
    smaller size.

    Beispiel:

    unsigned short int ui = 0;
    // unsigned short int --> integral promotion --> int
    cout << "max. unsigned short int = "<< ~ui; // int i=0 negiert ergibt -1.
    


  • [quote="out"] z.B. so:

    int i = 1;
    = ~(i << (sizeof(int)*8-1));
    cout << "max. int = "<< i;
    

    [quote]

    Danke ich glaube ich habe es verstanden.
    Mit sizeof(int) kriegt man die systeminterne Grösse von int raus (2 oder 4 byte), mit 8 multipliziert um in bits umzurechnen - 1 und verschiebt die Bits so um 15/ 31 stellen.
    Danach bekommt man die grösste negative und muss noch die Zahl negieren ?
    Ist das so richtig ?



  • Neuling._ schrieb:

    Aber wie krieg ich die grösstmögliche einer int raus ?

    #include <limits>
    std::numeric_limits<int>::max()
    
    oder
    
    #include <climits>
    INT_MAX
    
    oder
    
    (unsigned int)-1>>1
    


  • out schrieb:

    Neuling._ schrieb:

    Aber wie krieg ich die grösstmögliche einer int raus ?

    z.B. so:

    int i = 1;
    = ~(i << (sizeof(int)*8-1));
    cout << "max. int = "<< i;
    

    hm...

    ohne dass die Kenntnis der systeminternen verwendeten Bitanzahl für jeden Datentyp benutzt wird


Log in to reply