Manipulating BitsThis chapter describes bitwise operators and how to use bit masks.The applications included demonstrate calculations with parity bits, conversion of lowercase and capita
Trang 1Exercise 3
// -// sort_t.cpp
// Compares the performances of sorting algorithms
// quick sort and selection sort
// For this purpose, two identical arrays are dynamically
// generated and initialized with random numbers
// The times needed for sorting are displayed
//
-#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
void isort(int *v, int lenv);
// For qsort():
extern "C" int intcmp(const void*, const void*);
main()
{
unsigned int i, size;
int *numbers1, *numbers2;
long time1, time2;
cout << "\n The performance of the sorting algorithms"
<< "\n quick sort and selection sort"
<< "\n is being compared.\n\n"
<< "\nHow many numbers are to be sorted? ";
cin >> size;
numbers1 = new int[size];
numbers2 = new int[size];
cout << "\nThere are "
<< size << " random numbers to be generated.\n";
srand((unsigned)time(NULL)); // Initialize the
// random number generator for(i = 0 ; i < size ; ++i)
numbers1[i] = numbers2[i] = rand(); // Random numbers
cout << "\nSorting starts! Please wait.\n";
time(&time1); // Length of time
// for quick sort
qsort(numbers1, size, sizeof(int), intcmp);
time(&time2);
cout << "\nTime taken by the quick sort algorithm: "
<< time2 - time1 << " seconds.\n";
Trang 2cout << "\nI am sorting again Please wait!\n";
time(&time1); // Length of time isort(numbers2, size); // for selection sort time(&time2);
cout << "\nTime taken by the insertion sort algorithm: "
<< time2 - time1 << " seconds.\n"
<< "\nOutput sorted numbers? (y/n)\n\n";
char c; cin >> c;
if( c == 'Y' || c == 'y') for( i = 0 ; i < size ; ++i) cout << setw(12) << numbers1[i];
cout << endl;
return 0;
}
extern "C" int intcmp( const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
// -// isort() sorts an array of int values
// using the selection sort algorithm
void isort( int *a, int len) // Sort the array a of { // length len in ascending register int *b, *minp; // order
int *last, help;
last = a + len - 1; // Points to the last element
for( ; a <= last; ++a) // Search for the smallest { // element starting at a
minp = a; // minp points to the "current"
// smallest array element for( b = a+1; b <= last; ++b) // Search for the if( *b < *minp ) // minimum
minp = b;
help = *a, *a = *minp, *minp = help; // Swap }
}
Trang 3Exercise 4
// -// matrix.h : Represents dynamic matrices
//
-#ifndef _MATRIX_H_
#define _MATRIX_H_
#include <stdexcept>
#include <iostream>
using namespace std;
class Row
{
double *ro;
int size;
public:
Row( int s) { size = s; z = new double[s]; }
~Row(){ delete[]ro; }
double& operator[](int i)
{
if(i < 0 || i > size)
throw out_of_range("Row index: Out of Range\n");
return ro[i];
}
const double& operator[](int i) const
{
if(i < 0 || i > size)
throw out_of_range("Row index: Out of Range\n");
return ro[i];
}
};
class Matrix
{
private:
Row **mat; // Pointer to array of rows
int lines, cols; // Number of rows and columns
public:
Matrix(int ro , int co)
{
lines = ro; cols = co;
mat = new Row*[lines];
for(int i=0; i < lines; i++)
mat[i] = new Row(cols);
}
Trang 4Matrix( const Matrix& );
~Matrix() { for(int i=0; i < lines; i++)
delete mat[i];
delete[] mat;
} int getLines() const { return lines; } int getCols() const { return cols; }
Row& operator[](int i) {
if(i < 0 || i > cols) throw out_of_range("Row index: Out of Range\n"); return *mat[i];
}
const Row& operator[](int i) const {
if(i < 0 || i > cols) throw out_of_range("Row index: Out of Range\n"); return *mat[i];
}
// Assignments:
Matrix& operator=( const Matrix& );
Matrix& operator+=( const Matrix& );
};
#endif
// -// matrix.cpp : Defines methods of class Matrix
//
-#include "matrix.h"
Matrix:: Matrix( int ro, int co, double val) {
lines = ro; cols = co;
mat = new Row*[lines]; // Array of pointers to
// arrays of rows int i, j;
for(i=0; i < lines; i++) // Arrays of rows: {
mat[i] = new Row(cols); // Allocate memory for(j = 0; j < cols; ++j)
(*this)[i][j] = val; // and copy values }
}
Trang 5Matrix:: Matrix( const Matrix& m)
{
lines = m.lines; cols = m.cols; // Rows and columns
mat = new Row*[lines]; // Array of pointers
// to arrays of rows int i, j;
for(i=0; i < lines; i++) // Arrays of rows:
{
mat[i] = new Row(cols); // To allocate
// storage for( j = 0; j < cols; ++j)
(*this)[i][j] = m[i][j]; // and copy values
}
}
Matrix& Matrix::operator=(const Matrix& m)
{
int i, j; // Free "old" storage:
for(i=0; i < lines; i++)
delete mat[i];
delete[] mat;
lines = m.lines; cols = m.cols; // Rows, columns
mat = new Row*[lines]; // Array of pointers
// to arrays of rows for(i=0; i < lines; ++i) // Array of rows:
{
mat[i] = new Row(cols); // Allocate space
for( j = 0; j < cols; ++j)
(*this)[i][j] = m[i][j]; // and copy values
}
return *this;
}
Matrix& Matrix::operator+=( const Matrix& m)
{
int i, j;
if( cols == m.cols && lines == m.lines)
for( i=0; i < lines; ++i)
for( j=0; j < cols; ++j) (*this)[i][j] += m[i][j];
return *this;
Trang 6// -// matrix_t.cpp : Tests dynamic matrices
//
-#include "matrix.h"
void display( Matrix& m); // Output a matrix int main()
{ Matrix m(4,5);
try { int i,j;
for( i=0; i < m.getLines(); i++) for( j=0; j < m.getCols(); j++) m[i][j] = (double)i + j/ 100.0;
cout << "Matrix created" << endl;
display(m);
Matrix cop(m);
cout << "Copy generated." << endl;
display(cop);
cop += m;
cout << "Compute the sum:" << endl;
display(cop);
Matrix m1(4, 5, 0.0);
cout << "Initializing a matrix with 0:" << endl; display(m1);
m = m1;
cout << "Matrix assigned:" << endl;
display(m);
} catch(out_of_range& err) { cerr << err.what() << endl; exit(1); } return 0;
}
void display( Matrix& m) {
for(int i=0; i < m.getLines(); i++) {
for(int j=0; j < m.getCols(); j++) cout << m[i][j] << " ";
cout << endl;
} cin.get();
}
Trang 7Manipulating Bits
This chapter describes bitwise operators and how to use bit masks.The applications included demonstrate calculations with parity bits,
conversion of lowercase and capital letters, and converting binary
numbers Finally, the definition of bit-fields is introduced.
Trang 8Bitwise AND Result Bitwise inclusive OR Result
0 & 0
0 & 1
1 & 0
1 & 1
0 | 0
0 | 1
1 | 0
1 | 1
0 0 0 1
0 1 1 1
0 ˆ 0
0 ˆ 1
1 ˆ 0
1 ˆ 1
~0
~1
0 1 1 0
1 0
a = 5;
b = 12;
c = a & b;
c = a | b;
c = a ˆ b;
c = ~a;
unsigned int a, b, c;
0 0 0 0 1 0 1
0 0 0 1 1 0 0
0 0 0 1 1 0 1
0 0 0 1 0 0 1
1 1 1 1 0 1 0
0 0 0 0 1 0 0
Bit pattern
■ BITWISE OPERATORS
“True or False” table for bitwise operators
Examples
Trang 9䊐 Bit Coding Data
In cases where conservative use of memory is imperative, data often need to be bit coded,
a technique to represent information as individual bits Some examples of bit coded data can be found in file access rights or the status-word of a stream
To access bit coded data, you need to be able to read or modify individual bits C++ has six bitwise operators to perform these tasks:
■ Logical bitwise operators
■ Bitwise shift operators
<< Left shift >> Right shift
Operands for bitwise operators must have integral types Operands belonging to float
ordoubletypes are invalid
The boolean tables on the opposite page show the effect of the logical bitwise
opera-tors for individual bits If a bit is set, that is, if it has a value of 1, it will be interpreted as true If the bit is not set, and thus has a value of 0, it will be interpreted as false Exam-ples for each bitwise operator follow
The result type of a bitwise operation will be the integral type defined by the operand type If, for example, both operands are inttypes, the result will also be of an inttype
䊐 Arithmetic Type Conversions and Precedence
If the operands of a bitwise operator are of different types, normal arithmetic type con-version will occur If one operand type is an intand the other a long, the intvalue will be converted to longbefore the operation is performed
The logical bitwise operators &or|should not be confused with the logical &&and
||operators The latter do not affect individual bits but interpret the whole value of their operands as boolean, returning a boolean value The expression 1 && 2returns the value true, whereas 1 & 2has the value 0
The precedence of the bitwise NOT operator ∼is high, since ∼is a unary operator As you can see from the table of precedence in the appendix, both the binary operators &, ^, and|have low precedence However, their precedence is higher than that of the logical operators&&and||
Trang 10a = 12;
b = a << 3;
b = a >> 2;
unsigned int a, b;
0 0 0 0 0 0 1 1 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1
Bit pattern
// getbin_t.cpp: Defines the function getbin(), which // reads a binary number (ex 0101 ) // from the standard input, and returns // a value of type unsigned int
//
-#include <iostream>
using namespace std;
unsigned int getbin() {
char c;
unsigned int val = 0;
while ( (c = cin.get()) == ' ' || c == '\t' )
; // Ignore leading blanks and tabs
while( c == '0' || c == '1' ) // Read and convert { // the binary number val = (val << 1) | (c - '0');
c = cin.get();
}
return val;
}
■ BITWISE SHIFT OPERATORS
Right and left shift
Using shift operators