/*
    Print program to illustrate bitwise logic operations.
    
    1 byte = 8 bits. hence 1kb = 1024 bytes = 8192 bits 

    base 10 representation     101_decimal = 1*10^2 + 0*10^1 + 1*10^1 = 100+0+1
    base 2  representation     101_binary  = 1* 2^2 + 0* 2^1 + 1* 2^1 = 4+0+1    = 5 in base 10
    
    42_decimal = 32+8+2 = 1*2^5 + 1*2^3 + 1*2^1 = 101010_ binary
    
    1) Change 42 to -42 and explain what happens
    
    2) Change 42 to -1 and explain what happens

    See Nyhoff P51,P70
*/

#include <iostream>           // Include cin / cout streams for input/output
#include <iomanip>            // formatting specifies
#include <bitset>             // bitset function
using namespace std;          // Use this otherwise we need to write std::cout below.

int main()               
{          
   int number=-42;
   int mask=0b111;                                        // if compiler suppors C++14 otherwise its 7.

   const int bitsinint=8*sizeof(int);                     // number of bits in an integer

   cout << "number=" << number << endl;                   // prints number
   cout << "sizeof(int) ="                                // prints size of memory storing
        << sizeof(int) << " bytes  "                      // an integer
        << bitsinint << " bits" << endl;
                
// No easy way to print out the bits, except converting to bitset and printing
   cout << "number        ="
        << bitset<bitsinint>(number)
        << " in binary" << endl;

   cout << "mask          =" << bitset<bitsinint>(mask)            << " in binary" << endl;
 
//  bitwise logic operations
   cout << "number & mask =" << bitset<bitsinint>( number & mask ) << " (AND)" << endl;
   cout << "number | mask =" << bitset<bitsinint>( number | mask ) << " (OR)" << endl;
   cout << "^number       =" << bitset<bitsinint>( number ^ mask ) << " (XOR)" << endl;
   cout << "~number       =" << bitset<bitsinint>( ~number )       << " (NOT)" endl;

// Shift operations   
   cout << "number << 8   =" << bitset<bitsinint>( number << 8 )   << " (shift right 8)" << endl;
   cout << "number >> 3   =" << bitset<bitsinint>( number >> 3 )   << " (shift left 3 bits)" << endl;
   
   return 0;
}
