home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 February
/
Chip_2002-02_cd1.bin
/
chplus
/
funktor
/
f13_bitove_operatory.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2002-01-02
|
9KB
|
256 lines
//---------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
//---------------------------------------------------------------------------
// soubor: f13_bitove_operatory.cpp
// autor: Jaroslav Franek
// vytvoreno: 20011123
// copyright: (c) 2001 Jaroslav Franek
// umisteni: Chip CD, rubrika Chip Plus, 02/02
// reference: Jak se na funktor vola... II. dil, Chip 02/02
// testovano v : Borland C++ Builder 5.0
// nefunguje v : Microsoft Visual C++ .NET 7.0 (beta2), protoze tam chybi
// parcialni specializace sablonove tridy iterator_traits
// pro obycejny ukazatel
//
// komentar: jak napsat vlastni funtor - bitove operatory
// stl poskytuje funktory pro logicke operatory,
// ale ne pro bitove operatory, takze male cviceni:
// napisem si je sami, nebudeme je ale strkat do
// prostoru jmen 'std' - obycejny programator by nemel provadet
// rozsirovani nebo upravy rozhranni standardni knihovny
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// bitove NOT, operator ~
// T je ordinalni typ nebo trida pro kterou existuje pretizeny operator ~
//
//---------------------------------------------------------------------------
template <class T> struct bitwise_not
: public std::unary_function<T, T>
{
T operator ()(const T & arg) const
{
return ~arg;
}
};
//---------------------------------------------------------------------------
//
// bitove AND, operator &
// T je ordinalni typ nebo trida pro kterou existuje pretizeny operator &
//
//---------------------------------------------------------------------------
template <class T> struct bitwise_and
: public std::binary_function<T, T, T>
{
T operator ()(const T & arg1, const T & arg2) const
{
return arg1 & arg2;
}
};
//---------------------------------------------------------------------------
//
// bitove OR, operator |
// T je ordinalni typ nebo trida pro kterou existuje pretizeny operator |
//
//---------------------------------------------------------------------------
template <class T> struct bitwise_or
: public std::binary_function<T, T, T>
{
T operator ()(const T & arg1, const T & arg2) const
{
return arg1 | arg2;
}
};
//---------------------------------------------------------------------------
//
// bitove XOR, operator ^
// T je ordinalni typ nebo trida pro kterou existuje pretizeny operator ^
//
//---------------------------------------------------------------------------
template <class T> struct bitwise_xor
: public std::binary_function<T, T, T>
{
T operator ()(const T & arg1, const T & arg2) const
{
return arg1 ^ arg2;
}
};
//---------------------------------------------------------------------------
//
// vypis po bitech
// T je ordinalni typ
//
//---------------------------------------------------------------------------
template <class T>
std::ostream & write_bits(std::ostream & os, T x)
{
// kolik bitu ma jeden bajt, pro velikost pouzijeme typ std::size_t (tj. unsigned int)
static const std::size_t bits_per_byte = 8;
// kolik bitu ma hodnota typu T
static const std::size_t max_bits = bits_per_byte * sizeof(T);
int buff[max_bits];
// maska pro jednotlive bity, nastavime na nejnizsi bit
T mask(1);
// prevedeni x na bity
for ( std::size_t i = 0; i != max_bits ; ++i )
{
buff[max_bits - 1 - i] = (x & mask) ? 1 : 0;
mask <<= 1; // posuneme masku o 1 pozici na nizsi bit
}
// vypis
for ( std::size_t i = 0; i != max_bits ; ++i )
{
if ( !(os << buff[i]) )
{
break; // neco je spatne s 'os', prerusit smycku
}
}
return os;
}
//---------------------------------------------------------------------------
//
// priklady pouziti
//
//---------------------------------------------------------------------------
int main()
{
// nejdrive si pripravime kontejnery
const int N = 9;
int pole[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// a ted STL kontejnery
// tohle uz umime: cisla1 se inicializuji prvky pole 'pole'
std::vector<int> cisla1(pole, pole + N);
// tohle je nove, cisla2 se inicializuje prvky pole 'pole', ale pozpatku
// bohuzel Microsoft Visual C++ .NET 7.0 (beta2) tohle neskousne
// reverse_iterator si podrobne predstavime nekdy priste
std::vector<int> cisla2(std::reverse_iterator<int *>(pole + N),
std::reverse_iterator<int *>(pole));
// tohle je take nove: N prvku, kazdy nula
std::vector<int> cisla3(N, 0);
// vypiseme si je na obrazovku,
std::cout << "cisla1 : ";
std::copy(cisla1.begin(), cisla1.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n"
"cisla2 : ";
std::copy(cisla2.begin(), cisla2.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n"
"cisla3 : ";
std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
//*******************************************************************
// a ted provedeme toto : cisla3 = NEG cisla1
//
std::transform(cisla1.begin(), cisla1.end(), cisla3.begin(), bitwise_not<int>());
//*******************************************************************
// vypiseme si je na obrazovku,
std::cout << "NOT cisla1 : ";
std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
// posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
std::cout << "\n"
"cisla1[N-1] : ";
write_bits(std::cout, *(cisla1.end() - 1)); // o iteratorech podrobneji
std::cout << "\n" // az nekdy priste
"NOT cisla1[N-1] : ";
write_bits(std::cout, *(cisla3.end() - 1));
std::cout << std::endl;
//*******************************************************************
// a ted provedeme toto : cisla3 = cisla1 AND cisla2
//
std::transform(cisla1.begin(), cisla1.end(), cisla2.begin(), cisla3.begin(), bitwise_and<int>());
//*******************************************************************
// vypiseme si je na obrazovku,
std::cout << "cisla1 AND cisla2 : ";
std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
// posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
std::cout << "\n"
"cisla1[N-1] : ";
write_bits(std::cout, *(cisla1.end() - 1));
std::cout << "\n"
"cisla2[N-1] : ";
write_bits(std::cout, *(cisla2.end() - 1));
std::cout << "\n"
"cisla1[N-1] AND cisla2[N-1] : ";
write_bits(std::cout, *(cisla3.end() - 1));
std::cout << std::endl;
//*******************************************************************
// a ted provedeme toto : cisla3 = cisla1 OR cisla2
//
std::transform(cisla1.begin(), cisla1.end(), cisla2.begin(), cisla3.begin(), bitwise_or<int>());
//*******************************************************************
// vypiseme si je na obrazovku,
std::cout << "cisla1 OR cisla2 : ";
std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
// posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
std::cout << "\n"
"cisla1[N-1] : ";
write_bits(std::cout, *(cisla1.end() - 1));
std::cout << "\n"
"cisla2[N-1] : ";
write_bits(std::cout, *(cisla2.end() - 1));
std::cout << "\n"
"cisla1[N-1] OR cisla2[N-1] : ";
write_bits(std::cout, *(cisla3.end() - 1));
std::cout << std::endl;
//*******************************************************************
// a ted provedeme toto : cisla3 = cisla1 XOR cisla2
//
std::transform(cisla1.begin(), cisla1.end(), cisla2.begin(), cisla3.begin(), bitwise_xor<int>());
//*******************************************************************
// vypiseme si je na obrazovku,
std::cout << "cisla1 XOR cisla2 : ";
std::copy(cisla3.begin(), cisla3.end(), std::ostream_iterator<int>(std::cout, " "));
// posledni prvky vypiseme po bitech, aby bylo zrejme, ze se to povedlo
std::cout << "\n"
"cisla1[N-1] : ";
write_bits(std::cout, *(cisla1.end() - 1));
std::cout << "\n"
"cisla2[N-1] : ";
write_bits(std::cout, *(cisla2.end() - 1));
std::cout << "\n"
"cisla1[N-1] XOR cisla2[N-1] : ";
write_bits(std::cout, *(cisla3.end() - 1));
std::cout << std::endl;
// spravne vysledky si jiste dokazete overit sami
return 0;
}
//---------------------------------------------------------------------------