/**********************************************************************************
*** Etudiant : Nicolas Vion ***
*** Tp.cpp : Manipulation des bits ***
*** Formation : ASPE en informatique ***
*** Date : 19-11-2007 ***
**********************************************************************************/
/**********************************************************************************
Directives de pr�-processeur
**********************************************************************************/
#include <stdlib.h>
#include <limits.h>
/*definition de constante avec limite type entier specifique au compilateur utilise*/
#include <iostream> // permet l'utilisation fonctions E/S std
#include <math.h>// fonctions mathematique pour la fonction puissance
using namespace std;
/**********************************************************************************
Definition des constantes :
**********************************************************************************/
const unsigned TAILLE_d_un_INT = 8 * sizeof(unsigned);
/****************************************************************************************************
Instruction Compilateur (permet au compilateur de s'adapter au systeme) :
****************************************************************************************************/
/* Pour le systeme d exploitation Windows */
#ifdef WIN32
#define CLEARSCREEN "cls" //Pour la mise en pause
/* Pour le systeme d exploitation Linux */
#elif defined(linux)
#define CLEARSCREEN "clear" //Pour la mise en pause
/* Sinon on erreur car le systeme d exploitation n'est pas reconnu */
#else
#error not defined for this platform
#endif
/**********************************************************************************
Fonction validation de saisie en C++
**********************************************************************************/
unsigned valid_saisie ( void )
{
unsigned nb;
bool ok;
do
{
ok = true;
cout << endl << endl <<" Votre choix pour continuer ? "<< endl << endl;
if ( !(cin >> nb) )
{
cin.clear();
ok = false;
}
cin.ignore(80, '\n');
cout << endl;
} while ( !ok );
return ( nb );
}
/**********************************************************************************
Demande de la saisie du nombre entier
**********************************************************************************/
unsigned EntierTravail ( void )
{
unsigned nb = 0; //Variable contenant l entier. Par defaut, on initialise a zero.
cout << endl << endl << " Programme de Nicolas VION en ASPE Informatique" << endl ;
cout << " ____________________________________________________________" << endl << endl ;
cout << endl << endl;
cout <<"******************************************************************************"<<endl;
cout <<" M A N I P U L A T I O N D E B I T S : " << endl;
cout <<"******************************************************************************"<<endl<<endl<<endl<<endl;
cout <<" Entrez le nombre entier a traiter ( superieur a zero ) : " << endl;
do
{
nb = valid_saisie();
} while ( nb < 0 ); //Appel de la validation de saisie tant que le nombre fournit est negatif
return ( nb ); // On renvoie le nombre entier
}
/**********************************************************************************
Demande de la saisie du choix de l'operation � effectuer
**********************************************************************************/
unsigned Menu ( unsigned nb )
{
unsigned menu ; //Variable contenant le choix des operations sur les bits
cout <<"**********************************************************************************"<<endl;
cout <<" Le nombre entier que vous avez saisi est : " << nb << endl;
cout <<"**********************************************************************************"<<endl<<endl<<endl;
cout <<" Choisissez l'operation a effectuer : " << endl;
cout <<" ____________________________________" << endl<<endl<<endl;
cout <<" 1. Conversion en binaire de l'entier. " << endl;
cout <<" 2. Inversion de bits a partir d'une position definie. " << endl ;
cout <<" 3. Rotation de bits vers la gauche. " << endl ;
cout <<" 4. Choisir un autre entier. " << endl;
cout <<" 5. Quitter " << endl<<endl;
cout <<"**********************************************************************************"<<endl;
do
{
menu = valid_saisie();
} while ( menu < 0 || menu > 5);
/* Appel validation de saisie tant que le nombre saisi est different de ceux propos�*/
return ( menu );
}
/**********************************************************************************
Mise en attente du programme
**********************************************************************************/
void Pause(void)
{
cout << "\n Appuyer sur entree pour Continuer ";
cin.ignore(80, '\n');
}
/**********************************************************************************
Fonction affichage de bits :
**********************************************************************************/
void aff_bits( unsigned nb )
{
unsigned mask ;
//On decale le masque de 4*8 -1 position. ( Ne pas oublier le -1 sinon on ne pourra pas voir le premier bit )
mask = 1 << (TAILLE_d_un_INT - 1) ; //Avec TAILLE_d_un_INT = 8 * sizeof(unsigned)
cout << " " << nb << " en binaire : " << endl<<endl;
cout << " ";
/*********************************************************
* Boucle d'affichage des bits *
********************************************************/
for(unsigned c =1; c <= TAILLE_d_un_INT; c++)
{
cout << ( (nb & mask) ? "1" : "0") << " ";
// << " " permet de decaller tout les bits d'un espace
if ( (c % 4) == 0 )
// << " " permet de decaller de deux espaces tout les 4 bits
{
cout << " ";
}
nb <<= 1;
}
cout << endl;
}
/**********************************************************************************
Fonction inverse de bits :
**********************************************************************************/
void inverse( unsigned nb)
{
unsigned bits = 0, mask = 1 ;
unsigned p ; // Pour la position du traitement
unsigned n ;
/**********************************************************************************
Boucle de saisie de la position du traitement
**********************************************************************************/
do
{
cout << " Saisissez la position a partir de laquelle l'inversion commencera, "<< endl <<" (un nombre compris entre 1 et 32) ";
p = valid_saisie ();
cout << endl;
} while ( p < 1 || p > 32); //Validation du nombre. Il faut qu'il soit compris entre 1 et 32
/**********************************************************************************
Boucle de saisie du nombre de bits a modifier
**********************************************************************************/
do
{
cout << " Saisissez le nombre de bit(s) a modifier, "<< endl <<" (un nombre compris entre 1 et " << ( (32+1) - p ) << " ) ";
n = valid_saisie ();
} while ( n < 1 || n > ( (32+1) - p) ); //Validation du nombre
/**********************************************************************************
Affichage du resultat avec appel de la fonction aff_bits
**********************************************************************************/
cout << "**************************Avant l'Inverion : ****************************" << endl<<endl;
cout << " Le nombre saisi est : ";
aff_bits (nb);
cout << endl <<endl;
cout << "**************************Apres l'inversion : **************************" << endl<<endl;
for (unsigned cpt=1; cpt<(n); cpt++)
mask = (mask | (bits = unsigned(pow(2,cpt))) ); // La fonction pow necessite d'inclure la librairie math.h
mask <<= (p-1); // on fait un decalage du masque par la gauche de p-1 positions
nb = (nb ^ mask) ; // Inversion des n bits a la p ieme position du nombre
cout << " Nombre inverse du " <<p<< " eme bits et sur " <<n<< " position :" ;
aff_bits(nb);
cout << endl;
}
/**********************************************************************************
Fonction rotation de bits vers la gauche :
**********************************************************************************/
void rot_gauche( unsigned nb )
{
unsigned mask=1, bits = 0, b;
do
{
cout << " Saisissez le nombre de bit(s) qui effectuerons une rotation vers la droite "<<endl<<"( positif et inferieur ou egal a 32 ) "; b = valid_saisie();
cout << endl;
} while ( b < 0 || b > 32 );
for (unsigned cpt=1; cpt<(b); cpt++)
mask = (mask | (bits=unsigned(pow(2,cpt)) ) );
/*decalage vers la gauche des b bits pour les placer en bout de chaine*/
mask <<= (TAILLE_d_un_INT - b);
mask = (nb & mask);
mask >>= (TAILLE_d_un_INT - b);
/**********************************************************************************
affichage du nombre avant la rotation
**********************************************************************************/
cout << "*************************Avant la rotation*************************" << endl << endl;
aff_bits (nb);
cout << endl << endl;
// decalage vers la gauche du nombre de b bits
nb <<= b;
nb = (nb | mask);
/**********************************************************************************
affichage du nombre apres la rotation
**********************************************************************************/
cout << "*************************Apres decalage****************************" << endl << endl;
aff_bits (nb);
cout << endl << endl;
}
/**********************************************************************************
Fonction main
**********************************************************************************/
int main(void)
{
unsigned menu, nb;
nb = EntierTravail(); //Appel de la saisie du nombre � traiter
do
{
menu = Menu( nb ); //Appel de la saisie du numero de menu
switch (menu)
{
case 1 : aff_bits(nb); //Affichage du nombre en binaire
Pause();
system(CLEARSCREEN);
break;
case 2 : inverse(nb); //Affichage de l'inverse a la p ieme position
Pause();
system(CLEARSCREEN);
break;
case 3 :
rot_gauche(nb); //Affichage de la rotation
Pause();
system(CLEARSCREEN);
break;
case 4 : nb = EntierTravail(); //Redemande de saisie du nombre
system(CLEARSCREEN);
break;
}
}while ( menu < 0 || menu > 6 || menu !=5);
cout << "Merci d'avoir essaye ce programme !" << endl << endl ;
return 0;
}