Andy Wang Object Oriented Programming in C++ COP 3330 Bitwise Operators Andy Wang Object Oriented Programming in C++ COP 3330
Bits and Bytes A bit is the smallest unit of storage in a computer It store 0 or 1 A byte consists of 8 bits Smallest unit of directly addressable storage The smallest built-in data type is the char 1 byte on most systems What if we want to access individual bits? Must use the bitwise operators Caution: bitwise operators may be machine dependent Most machines use 2’s complement format
Base Conversion 1510 -> 11112 15 % 2 = 1 // least significant bit 15 / 2 = 7 7 % 2 = 1 // next bit 7 / 2 = 3 3 % 2 = 1 // next bit 3 / 2 = 1 1 % 2 = 1 // next bit 1 / 2 = 0 // terminate
Base Conversion 11112 1510 1x23 + 1x22 + 1x21 + 1x20 = 8 + 4 + 2 + 1 = 15
Two’s Complement Suppose we have 4-bit integers Non-negative numbers Just convert base 10 numbers to base 2 010 = 00002 110 = 00012 210 = 00102 To add two numbers, just add the corresponding bits 110 + 210 = 00012 + 00102 = 00112 = 1x21 + 1x20 = 310
Two’s Complement Negative numbers Flip all the bits of a non-negative numbers, then add 1 -110 = flip(00012) + 1 = 11102 + 1 = 11112 010 = flip(00002) + 1 = 11112 + 1 = 00002 If the uppermost bit is one, the number is negative To add a non-negative number with a negative number, just add 110 + (-1)10 = 00012 + 11112 = 00002 = 0
Two’s Complement To add two negative numbers, just add as well (-1)10 + (-1)10 = 11112 + 11112 = 11102 To decode a negative number, subtract the number by 1, and flip all the bits 11102 = negative flip(11102 – 1) = negative flip(11012) = negative 00102 = negative (1x21) = negative 210
The Bitwise Operators Operator Name Arity Description & Bitwise AND Binary Similar to the && operator, but on a bit-by-bit basis. | Bitwise OR Similar to the || operator, but on a bit-by-bit basis. ^ Bitwise Exclusive OR Set to 1 if one of the corresponding bits is 1, or set to 0 otherwise. ~ Complement Unary Flips the bits in the operand.
The Bitwise Operators Operator Name Arity Description << Left shift Binary Shifts the bits of the first operand to the left by the number of bits specified in the second operand. Right fill with 0 bits. >> Right shift Shifts the bits of the first operand to the right by the number of bits specified in the second operand. Left fill with 0’s for positive numbers, 1’s for negatives (machine dependent).
Shortcut Assignment Operators x &= y means x = x & y x |= y means x = x | y x ^= y means x = x ^ y x <<= y means x = x << y x >>= y means x = x >> y
Examples Suppose we have the following code short x = 6891; short y = 11318; Assume short is 2 bytes (16 bits) x: 00011010 11101011 y: 00101100 00110110 ---------------------- x & y:
Examples Suppose we have the following code short x = 6891; short y = 11318; Assume short is 2 bytes (16 bits) x: 00011010 11101011 y: 00101100 00110110 ---------------------- x & y: 00001000 00100010 (2082)
Examples ------------------------- x: 00011010 11101011 y: 00101100 00110110 ------------------------- x | y: x ^ y:
Examples ------------------------- x: 00011010 11101011 y: 00101100 00110110 ------------------------- x | y: 00111110 11111111 (16127) x ^ y:
Examples ------------------------- x: 00011010 11101011 y: 00101100 00110110 ------------------------- x | y: 00111110 11111111 (16127) x ^ y: 00110110 11011101 (14045)
Examples ------------------------- x: 00011010 11101011 ---------------------------- x << 2: y: 00101100 00110110 ------------------------- y >> 4: ~x:
Examples ------------------------- x: 00011010 11101011 ---------------------------- x << 2: 01101011 10101100 (27564) y: 00101100 00110110 ------------------------- y >> 4: ~x:
Examples ------------------------- x: 00011010 11101011 ---------------------------- x << 2: 01101011 10101100 (27564) y: 00101100 00110110 ------------------------- y >> 4: 00000010 11000011 (707) ~x:
Examples ------------------------- x: 00011010 11101011 ---------------------------- x << 2: 01101011 10101100 (27564) y: 00101100 00110110 ------------------------- y >> 4: 00000010 11000011 (707) ~x: 11100101 00010100 (-6892)
Code Examples http://www.cs.fsu.edu/~myers/cop3330/examples/bit wise/ex1.cpp
Code Examples #include <iostream> #include <iomanip> using std::cout; using std::endl; int main() { short x = 6891, y = 11318; cout << "x = " << x << "\ny = " << y << endl; cout << "x & y = " << (x & y) << endl; cout << "x | y = " << (x | y) << endl; cout << "x ^ y = " << (x ^ y) << endl; cout << "x << 2 = " << (x << 2) << endl; cout << "y >> 4 = " << (y >> 4) << endl; cout << "~x = " << ~x << endl; }
Examples from Dietel http://www.cs.fsu.edu/~myers/deitel5c++/ch22/Fig22_ 06/fig22_06.cpp Display bit values http://www.cs.fsu.edu/~myers/deitel5c++/ch22/Fig22_ 08/fig22_08.cpp &, |, ^, and ~ bitwise operators http://www.cs.fsu.edu/~myers/deitel5c++/ch22/Fig22_ 11/fig22_11.cpp << and >> bitwise operators
fig22_06.cpp #include <iostream> #include <iomanip> using namespace std; void displayBits(unsigned value) { const int SHIFT = 8*sizeof(unsigned) -1; const unsigned MASK = 1 << SHIFT; // 1000…. cout << setw(10) << value << “ = “; for (unsigned j = 1; j < SHIFT + 1; j++) { if (value & MASK) cout << ‘1’; value <<= 1; else cout << ‘0’; if (j % 8 == 0) cout << ‘ ‘; } cout << endl;
fig22_06.cpp int main() { unsigned inputValue; cout << “Enter an unsigned integer: “; cin >> inputValue; displayBits(inputValue); return 0; }
fig22_08.cpp #include <iostream> #include <iomanip> using namespace std; void displayBits(unsigned value) { const int SHIFT = 8*sizeof(unsigned) -1; const unsigned MASK = 1 << SHIFT; cout << setw(10) << value << “ = “; for (unsigned j = 1; j < SHIFT + 1; j++) { if (value & MASK) cout << ‘1’; value <<= 1; else cout << ‘0’; if (j % 8 == 0) cout << ‘ ‘; } cout << endl;
fig22_08.cpp int main() { unsigned number1, number2, mask, setBits; number1 = 179876355; mask = 1; cout << “The result of combining the following\n”; displayBits(number1); displayBits(mask); cout << “using the bitwise AND operator & is\n”; displayBits(number1 & mask); number1 = 15; setBits = 241; displayBits(number1); displayBits(setBits); cout << “using the bitwise OR operator | is\n”; displayBits(number1 | setBits);
fig22_08.cpp number1 = 139; number2 = 199; cout << “The result of combining the following\n”; displayBits(number1); displayBits(number2); cout << “using the bitwise exclusive OR operator ^ is\n”; displayBits(number1 ^ number2); number1 = 21845; cout << “\nThe one’s complement of\n”; displayBits(number1); cout << “is”; displayBits(~number1); return 0; }
fig22_11.cpp #include <iostream> #include <iomanip> using namespace std; void displayBits(unsigned value) { const int SHIFT = 8*sizeof(unsigned) -1; const unsigned MASK = 1 << SHIFT; cout << setw(10) << value << “ = “; for (unsigned j = 1; j < SHIFT + 1; j++) { if (value & MASK) cout << ‘1’; value <<= 1; else cout << ‘0’; if (j % 8 == 0) cout << ‘ ‘; } cout << endl;
fig22_11.cpp int main() { int number1 = -2000; cout << “The result of left shifting\n”; displayBits(number1); cout << “8 bit positions using the left-shift operator is\n”; displayBits(number1 << 8); cout << “\nThe result of right shifting\n”; cout << “8 bit positions using the right-shift operator is\n”; displayBits(number1 >> 8); return 0; }
BitFlags Examples http://www.cs.fsu.edu/~myers/cop3330/examples/bit wise/bitflags/ Set up to store a set of on/off flags On a system with 4-byte integers, a BitFlag object can store 32 flags (using one variable for all flags)
bitflags.h class BitFlags { public: BitFlags(); void Set(int num); void Unset(int num); void Flip(int num); bool Query(int num) const; private: int Mask(int num) const; unsigned int flags; const int numflags; };
bitflags.cpp #include <iostream> #include “bitflags.h” BitFlags::BitFlags() : numflags(sizeof(int)*8) { flags = 0; } int BitFlags::Mask(int num) const { return (1 << num); void BitFlags::Set(int num) { flags = flags | Mask(num);
bitflags.cpp void BitFlags::Unset(int num) { flags = flasg & ~Mask(num); } void BitFlags::Flip(int num) { flags = flags ^ Mask(num); Bool BitFlags::Query(int num) { return (flags & Mask(num));
main.cpp #include <iostream> #include “bitflags.h” using namespace std; int main() { BitFlags b; for (int j = 0; j < 32; j += 2) b.Set(j); for (int j = 0; j < 32; j++) // reverse order… cout << b.Query(j); cout << endl;
main.cpp for (int j = 0; j < 32; j++) cout << b.Query(j); b.Set(5); b.Unset(8); b.Flip(31); for (int j = 0; j < 32; j++) cout << b.Query(j); cout << endl; return 0; }