• Advertisement
Sign in to follow this  

binary, bitwise etc

This topic is 4304 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Does anyone know any good tutorials on binary and the bitwise operators. I've been seeing more and more of it being used in example code so I think I should practice using these things. I'm not really sure when/why to use this stuff yet so I want to learn more about it in general. Anyone point me to a good resource?

Share this post


Link to post
Share on other sites
Advertisement
The Wikipedia entry for the binary number system seems like a good reference. Plus there's a bunch of links to the bitwise operators around the center of the page. You'll also want to read up on Hexadecimal since most programming languages only allow decimal or hex.

Share this post


Link to post
Share on other sites
When you see the word 'bitwise', that means the operation is carried out for each bit. For example, given A and B of length n bits, a bitwise operator X works as follow:

A X B = A(0) X B(0), A(1) X B(1), ... , A(n-1) X B(n-1)

That is, for each bit in A and B, performs X.

Share this post


Link to post
Share on other sites
well I've done some reading and I think I'm ready to try some exercises. I'm gonna google around and try to find some. If anyone knows any good exercises I should try please post a link. If you wanna make some up that's fine too. Thanks :)

Share this post


Link to post
Share on other sites
Here's a couple of exercises from me:

  • A library function, lib_gettime(), returns a 16-bit integer that indicates the current time in the following format:
    Starting from the least significat bit,
    The first 6 bit is the second
    The next 6 bit is the minute
    The last 4 bit is the hour in 12-hour format

    hour second
    | |
    +--+ +-----+
    | | | |
    XXXX XXXX XXXX XXXX
    | |
    +-----+
    |
    minute

    Extract second, minute, and hour from this 16-bit number into three separate numbers.

  • RGBA colors contain four components red, green, blue, and alpha. You are given the components in four 8-bit numbers each of which ranged from 0-255. Using bitwise operators, combine these four numbers into one 32-bit number. (a) The order is: R-G-B-A. (b) B-G-R-A.

    Share this post


    Link to post
    Share on other sites
    Also, if you're using C++, std::bitset is a handy container for working with binary values. It lets you output in binary in a straightforward manner, unlike trying to output an int in binary format......

    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by alnite
    Here's a couple of exercises from me:

  • A library function, lib_gettime(), returns a 16-bit integer that indicates the current time in the following format:
    Starting from the least significat bit,
    The first 6 bit is the second
    The next 6 bit is the minute
    The last 4 bit is the hour in 12-hour format

    hour second
    | |
    +--+ +-----+
    | | | |
    XXXX XXXX XXXX XXXX
    | |
    +-----+
    |
    minute

    Extract second, minute, and hour from this 16-bit number into three separate numbers.

  • RGBA colors contain four components red, green, blue, and alpha. You are given the components in four 8-bit numbers each of which ranged from 0-255. Using bitwise operators, combine these four numbers into one 32-bit number. (a) The order is: R-G-B-A. (b) B-G-R-A.


  • Thanks. I just popped on to check the forum. I'm gonna try these tomorrow when I have some spare time. :)

    Share this post


    Link to post
    Share on other sites
    Well here is what I came up with for the first exercise from alnite.


    #include <ctime>
    #include <cstdlib>
    #include <iostream>
    #include <iomanip>

    using namespace std;

    int lib_getTime( void )
    {
    int hour = 1 + (rand() % 12);
    int min = rand() % 60;
    int sec = rand() % 60;

    return ( (hour << 12) | (min << 6) | sec );
    }

    void displayBinTime( int& t )
    {
    cout << "Time in binary: ";
    for ( int i = 15; i >= 0; i-- )
    {
    if ( t & (1 << i ) )
    cout << '1';
    else
    cout << '0';

    if ( i != 0 && i % 4 == 0 )
    cout << ':';
    }

    cout << endl;
    }

    int main()
    {
    srand( time(0) ); // seed random number generator

    int time = lib_getTime();
    int hour = time >> 12;
    int min = time >> 6 & 0x3F;
    int sec = time & 0x3F;

    cout << "Time in decimal: ";
    cout << setw(2) << setfill('0') << hour << ':'
    << setw(2) << setfill('0') << min << ':'
    << setw(2) << setfill('0') << sec << endl;

    displayBinTime(time);

    return 0;
    }



    Seems to work. I'm gonna check out the next one :)

    Share this post


    Link to post
    Share on other sites
    Say you have a char in binary:

    1111 1111

    Now when this is upcast to an int do we get zeros appended to the left?:

    0000 0000 1111 1111

    Is that right? So now we can left-shift 8 more places?

    I've been trying to combine the 4 chars representing my red, green, blue and alpha into a 32 bit number( im using long long ). For some reason, even when I cast the chars up to long long and then try to shift them it's not working properly but if I just start out with the chars as long long instead of char, it seems to work fine. I'm assuming the cast is not working as I thought it was. Can anyone offer any insight?

    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by nomichi
    Now when this is upcast to an int do we get zeros appended to the left?:


    Depends on whether you are working with signed or unsigned values. Unsigned values will be 0-extended, while signed values will be sign-extended.

    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by Fruny
    Quote:
    Original post by nomichi
    Now when this is upcast to an int do we get zeros appended to the left?:


    Depends on whether you are working with signed or unsigned values. Unsigned values will be 0-extended, while signed values will be sign-extended.


    ok I tested with an unsigned char and it converts correctly. I'm not sure what sign-extended means though. I guess when working with bits I should always use unsigned values?

    I managed to get my program working without using unsigned. It was a pain but here it is. I'm gonna go back and see how much easier I can do it with unsigned chars.


    #include <ctime>
    #include <cstdlib>
    #include <iostream>
    #include <iomanip>
    using namespace std;

    typedef long long int32;

    void PackedColor( int32& val )
    {
    char r = rand() % 256;
    char g = rand() % 256;
    char b = rand() % 256;
    char a = rand() % 256;

    cout << "Generated RGBA numbers: " << endl;
    cout << "R:" << (r & 0xFF) << ' '
    << "G:" << (g & 0xFF) << ' '
    << "B:" << (b & 0xFF) << ' '
    << "A:" << (a & 0xFF) << endl << endl;

    val = ( 0xFFFFFFFF & (r&0xFF) << 24 |
    0xFFFFFFFF & (g&0xFF) << 16 |
    0xFFFFFFFF & (b&0xFF) << 8 |
    0xFFFFFFFF & (a&0xFF) );
    }

    void OutputBin( int32& data )
    {
    for ( int i = 31; i >= 0; i-- )
    {
    if ( data & (int32(1) << i) )
    cout << '1';
    else
    cout << '0';

    if ( i % 4 == 0 )
    cout << ' ';
    }

    cout << endl << endl;

    }

    int main()
    {
    srand( time (0) );

    int32 rgba = 0; // 32bit value to hold our packed RGBA

    cout << "Verify our 32bit datatype is empty: " << endl;
    OutputBin(rgba);
    PackedColor(rgba);
    cout << "Color packed into 32bit datatype: " << endl;
    OutputBin(rgba);

    // unpack our color values into seperate 8bit chars
    char red = ((rgba >> 24) & 0xFF);
    char green = ((rgba >> 16) & 0xFF);
    char blue = ((rgba >> 8) & 0xFF);
    char alpha = (rgba & 0xFF);

    cout << "Values unpacked from binary: " << endl;
    cout << "R:" << (red & 0xFF) << ' '
    << "G:" << (green & 0xFF) << ' '
    << "B:" << (blue & 0xFF) << ' '
    << "A:" << (alpha & 0xFF) << endl << endl;

    unsigned char test = 255;
    int32 test2 = test;
    cout << test2 << endl;

    return 0;
    }

    Share this post


    Link to post
    Share on other sites
    Another question I had while converting to the easier method...

    Is this:

    val = ( 0xFFFFFFFF & (r & 0xFF) << 24 |
    0xFFFFFFFF & (g & 0xFF) << 16 |
    0xFFFFFFFF & (b & 0xFF) << 8 |
    0xFFFFFFFF & (a & 0xFF) );

    faster than this?

    val = static_cast<int32>(r) << 24 |
    static_cast<int32>(g) << 16 |
    static_cast<int32>(b) << 8 |
    static_cast<int32>(a);

    I'm assuming it is either faster or uses less memory? When you do a cast does it essentially make that variable take up the amount of memory that what you cast to would normally use? Even if it's temporary I would imagine all that overhead adds up in big projects.

    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by nomichi
    ok I tested with an unsigned char and it converts correctly. I'm not sure what sign-extended means though. I guess when working with bits I should always use unsigned values?


    If the (signed) number is negative, i.e. if its sign bit is 1, the extra space will be filled with ones. This may or may not be what you need, depending on the actual operation you want to perform. Sometimes an unsigned value makes sense, sometimes only a signed value will do.

    unsigned 00000000 → 0000000000000000 zero-extend
    unsigned 11111111 → 0000000011111111 zero-extend
    signed 00000000 → 0000000000000000 sign-extend
    signed 11111111 → 1111111111111111 sign-extend


    [Edited by - Fruny on May 10, 2006 1:00:25 AM]

    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by Fruny
    Quote:
    Original post by nomichi
    ok I tested with an unsigned char and it converts correctly. I'm not sure what sign-extended means though. I guess when working with bits I should always use unsigned values?


    If the (signed) number is negative, i.e. if its sign bit is 1, the extra space will be filled with ones. This may or may not be what you need, depending on the actual operation you want to perform. Sometimes an unsigned value makes sense, sometimes only a signed value will do.

    unsigned 00000000 → 0000000000000000 zero-extend
    unsigned 11111111 → 0000000011111111 zero-extend
    signed 00000000 → 0000000000000000 sign-extend
    signed 11111111 → 1111111111111111 sign-extend


    Oh I see. That explains why the signed char converted ok sometimes. That sign bit must of been 0 in those cases. Thanks for the explanation. :)

    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by simon10k
    This site explains binary operations quite well. -C/C++.


    Thanks, I will check it out.

    Share this post


    Link to post
    Share on other sites
    Sign in to follow this  

    • Advertisement