gegeben Zahl binär ausgeben



  • Hallo zusammen,

    ich lerne gerade C++ mit dem Buch Ulrich Breymann - "Der Programmierer"
    Bei einer übungsaufgabe komme ich nicht weiter, auch nicht wenn ich mir die Lösung anschaue.

    Schreiben Sie eine Schleife, die eine gegebene Zahl binr ausgibt, indem Sie mit geeigneten Bit-Operationen prüfen, welche Bits der Zahl gesetzt sind.

    int main() {
       cout << "Eingabe einer Zahl: ";
       int zahl = 0;
       cin >> zahl;
       int anzahlDerBytes = sizeof zahl;
       int anzahlDerBits = 8 * anzahlDerBytes;
       cout <<" binär :  ";
       for(int k = anzahlDerBits-1; k >= 0 ; --k) {
          if(zahl & (1 << k)) {
             cout << "1";
          }
          else {
             cout << "0";
          }
       }
       cout << endl;
    }
    

    Bis zu der Schleife kann ich das Ganze nachvollziehen, weiter komme ich nicht.
    Könnte mir vielleicht jemand einen neuen Denkansatz liefern?

    Viele Grüße & besten Danke!



  • Nun ja, die Schleife tut eigentlich nichts anderes, als Stück für Stück zu überprüfen, ob ein Bit gesetzt ist.

    Nehmen wir mal an es ist die Zahl 4, und ein int ist 2 Byte groß.
    Das sieht binär so aus:
    0000 0000 0000 0100
    Dann fängt die Schleife an, und k ist beim ersten Durchlauf 15.
    Der << Shift Operator verschiebt 1 also um 15 Stellen.
    aus 0000 0000 0000 0001 wird 1000 0000 0000 0000
    Der prüft jetzt, ob das & bitweise-Und stimmt, das heißt, ob in diesem Fall im ganz linken Bit die 1 gesetzt ist, wenn ja, gibt der eine 1 aus, wenn nein, eine 0.
    In diesem Fall also eine 0.
    Dann geht es weiter:
    k ist nur noch 14, die 1 wird also um 14 Stellen verschoben.
    Es wird 0100 0000 0000 0000 geprüft, also ob das 14.Bit gesetzt ist.
    Dann ob das 13., 12., 11., etc.
    Verstehst du es jetzt?



  • Wär schon mal nicht schlecht, LSB 0:

    #include <iostream>
    #include <iterator>
    
    template<typename T>
    std::string binary(T t)
    {
            unsigned short amountBits =  sizeof(T) * 8;
            std::string rval(amountBits, '0');
            while(amountBits--)
                    if((t >>= 1) & 1)
                            ++rval[amountBits - 1];
    
            return rval;
    }
    
    int main()
    {
            for(;;)
                    std::cout << binary( *std::istream_iterator<int>(std::cin) ) << '\n';
    }
    

    Und dann noch die TMP Version mit MSB 0:

    #include <iostream>
    
    #define split1(x, n)  (sizeof(x) > n ? x[n] : '\0')
    #define split2(x, n)  split1(x, n), split1(x, n + 1)
    #define split4(x, n)  split2(x, n), split2(x, n + 2)
    #define split8(x, n)  split4(x, n), split4(x, n + 4)
    #define split16(x, n) split8(x, n), split8(x, n + 8)
    #define split32(x, n) split16(x, n), split16(x, n + 16)
    #define split64(x, n) split32(x, n), split32(x, n + 32)
    #define split128(x, n) split64(x, 0), split64(x, n + 64)
    #define split(x) split128(x, 0)
    
    template<typename T, T t, unsigned short index = sizeof(T) * 8>
    struct binary
    {
            typedef binary<T, (t >> 1), index - 1> nextT;
            static constexpr char array[] = {'0' + (t & 1), split(nextT::array), '\0'};
    };
    template<typename T, T t, unsigned short index>
    constexpr char binary<T, t, index>::array[];
    
    template<typename T, T t>
    struct binary<T, t, 0>
    {
            static constexpr char array[sizeof (T) * 8]{t & 1};
    };
    
    int main()
    {
            std::cout << binary<int, 100>::array << '\n';
    }
    

    🤡 Wers toppt kriegt nen Keks.

    Edit: Falls es den Mods nicht gefällt, bitte einfach splitten.



  • Sone schrieb:

    🤡 Wers toppt kriegt nen Keks.

    #include <climits>
    #include <bitset>
    #include <iostream>
    
    int main( )
    {
    	std::cout << std::bitset< sizeof( int ) * CHAR_BIT >( 42 ) << "b\n";
    }
    

    Behalt den Keks ... 🙄



  • Swordfish schrieb:

    Sone schrieb:

    🤡 Wers toppt kriegt nen Keks.

    #include <climits>
    #include <bitset>
    #include <iostream>
    
    int main( )
    {
    	std::cout << std::bitset< sizeof( int ) * CHAR_BIT >( 42 ) << "b\n";
    }
    

    Behalt den Keks ... 🙄

    Lappen, es ging um die TMP -Version.



  • Hallo Nathan,

    dankeschön. Jetzt ist mir das ganze klar geworden!

    Viele Grüße



  • Sone schrieb:

    #include <iostream>
    #include <iterator>
    
    template<typename T>
    std::string binary(T t)
    {
            unsigned short amountBits =  sizeof(T) * 8;
            std::string rval(amountBits, '0');
            while(amountBits--)
                    if((t >>= 1) & 1)
                            ++rval[amountBits - 1];
    
            return rval;
    }
    
    int main()
    {
            for(;;)
                    std::cout << binary( *std::istream_iterator<int>(std::cin) ) << '\n';
    }
    

    Das Ergebnis ist dann:

    1 00000000000000000000000000000000
    2 00000000000000000000000000000010
    3 00000000000000000000000000000010
    4 00000000000000000000000000000100
    5 00000000000000000000000000000100
    

    Da müsstest Du nochmal nacharbeiten.



  • tntnet schrieb:

    Sone schrieb:

    #include <iostream>
    #include <iterator>
    
    template<typename T>
    std::string binary(T t)
    {
            unsigned short amountBits =  sizeof(T) * 8;
            std::string rval(amountBits, '0');
            while(amountBits--)
                    if((t >>= 1) & 1)
                            ++rval[amountBits - 1];
    
            return rval;
    }
    
    int main()
    {
            for(;;)
                    std::cout << binary( *std::istream_iterator<int>(std::cin) ) << '\n';
    }
    

    Das Ergebnis ist dann:

    1 00000000000000000000000000000000
    2 00000000000000000000000000000010
    3 00000000000000000000000000000010
    4 00000000000000000000000000000100
    5 00000000000000000000000000000100
    

    Da müsstest Du nochmal nacharbeiten.

    Komsich. Ich bin total sicher, es ging als ich es getestet hab. Warte, ich fix das gleich.



  • Musst du nicht schön langsam ins Bett!?

    #include <cctype>
    #include <string>
    #include <iostream>
    #include <iterator>
    
    template<typename T>
    std::string binary(T t)
    {
    	unsigned short amountBits = sizeof(T) * CHAR_BIT;
    	std::string rval( amountBits, '0' );
    
    	while( amountBits-- )
    		if( t & ( 1 << amountBits - 1 ) )
    			rval[ sizeof(T) * CHAR_BIT - amountBits ]++;
    
    	return rval;
    }
    
    int main()
    {
            for(;;)
                    std::cout << binary( *std::istream_iterator<int>(std::cin) ) << '\n';
    }
    


  • Swordfish schrieb:

    Musst du nicht schön langsam ins Bett!?

    Ich werd wohl um 12 langsam das Licht ausmachen.

    Fixed:

    #include <iostream>
    #include <iterator>
    
    template<typename T>
    std::string binary(T t)
    {
            unsigned short amountBits =  sizeof(T) * 8;
            std::string rval(amountBits, '0');
            for(;amountBits--;t >>= 1)
                    if(t & 1)
                            ++rval[amountBits];
    
            return rval;
    }
    
    int main()
    {
            for(;;)
                    std::cout << binary( *std::istream_iterator<int>(std::cin) ) << '\n';
    }
    


  • Error	1	error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)	main.cpp	19
    


  • Swordfish schrieb:

    Error	1	error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)	main.cpp	19
    

    Haha, unterstützt dein Compiler kein argument dependent name lookup? :p
    Aber jetz' mal ohne Scheiß, da stimmt was nicht...


  • Mod

    Sone schrieb:

    Haha, unterstützt dein Compiler kein argument dependent name lookup? :p

    Und wo soll er hier deiner Meinung nach was finden?



  • Sone schrieb:

    Haha, unterstützt dein Compiler kein argument dependent name lookup? :p

    roflmao, ymmd!! 😃



  • SeppJ schrieb:

    Sone schrieb:

    Haha, unterstützt dein Compiler kein argument dependent name lookup? :p

    Und wo soll er hier deiner Meinung nach was finden?

    Im Namensraum std .

    N3337, Header <string> Synopsis:

    namespace std
    {
        //...................
        template<class charT, class traits, class Allocator>
        basic_ostream<charT, traits>&
        operator<<(basic_ostream<charT, traits>& os,
        const basic_string<charT,traits,Allocator>& str);
    

    Wenn er std::string findet ( <iostream> also <string> einbindet), muss er auch den Operator finden. Das wäre meine Logik.



  • stringfwd ftw.



  • Sone schrieb:

    [...] ( <iostream> also <string> einbindet) [...] Das wäre meine Logik.

    Your logic is flawed.

    // edit: *filmzitateratethreadaufmachengeh'*


Anmelden zum Antworten