acceder au document
/*******************************************************************************
author: Pierre-Emmanuel Périllon
date: 30/05/2007
encoding: utf8
level: beginner+
langage: C++ (without class), comments in french
licence: Creative common by+nc+sa. see http://creativecommons.org/
website: http://tutorat.univ-lyon1.fr/
build: g++ -Wall if3_2006_decembre.cpp -o out
********************************************************************************
PROBLEME
parser une chaine contenant uniquement un nombre ou un point. ex "35" ou "0.795"
*/
#include <iostream>
using namespace std;
/**
* separer la partie entiere de la partie décimale.
*/
void separerToken(const char src[], char tabEnt[], char tabFract[])
{
int i = 0;
int j = 0;
/* copier la partie entier */
while ( ( src[i] != '.' ) && ( src[i] != '\0' ) )
{
tabEnt[i] = src[i];
i++;
cout << "*";
}
tabEnt[i] = '\0'; //ne pas oublier le caractère de stop
/* si on sort grace à un point il faut sauter le point pour ne pas le recopier */
if ( src[i] != '\0' )
{
i++;
}
while ( src[i] != '\0' )
{
tabFract[j] = src[i];
i++;
j++;
cout << "*";
}
tabFract[j] = '\0';
}
/**
* convertir, on utilise le polynome de Horner
*/
int parserPartieEntiere( const char src[] )
{
int i = 0;
unsigned int partieEntiere = 0;
while ( src[i] != '\0' )
{
partieEntiere = partieEntiere * 10 + ( src[i] - '0'); // on somme des positifs
i++;
cout << "*";
}
return partieEntiere;
}
/**
* convertir, on utilise le polynome de Horner modifié
* on doit faire attention au cas .0001 vis à vis de 0.1,
* c'est pourquoi on n'utilise pas la fonction ci dessus
*/
double parserPartieDecimale( const char src[] )
{
int i = 0;
unsigned int partieDecimale = 0;
double diviseur = 1.0;
while ( src[i] != '\0' )
{
partieDecimale = partieDecimale * 10 + ( src[i] - '0'); // on somme des positifs
diviseur *= 10.0f;
i++;
cout << "*";
}
return partieDecimale/diviseur;
}
/**
* atoi,
*/
float convertirChaineVersFloat( const char src[] )
{
// int -> 2^32 = 4294967296 soit 10 char, inutile d'en mettre bcp plus.
char tabEnt[16];
char tabFract[16];
// découper
separerToken( src, tabEnt, tabFract);
return (float) parserPartieEntiere( tabEnt ) + parserPartieDecimale( tabFract );
}
/**
* methode optimisée qui a une empreinte plus petite en mémoire
* et fait moins parcours dans la chaine.
*/
float convertirChaineVersFloat2( const char src[] )
{
unsigned int i = 0;
unsigned int partieEntiere = 0;
unsigned int partieDecimale = 0;
double diviseur = 1.0;
while ( ( src[i] != '.' ) && ( src[i] != '\0' ) )
{
partieEntiere = partieEntiere * 10 + ( src[i] - '0'); // on somme des positifs
i++;
cout << "+";
}
/* si on sort grace à un point il faut sauter le point pour ne pas le
recopier */
if ( src[i] != '\0' )
{
i++;
}
while ( src[i] != '\0' )
{
partieDecimale = partieDecimale * 10 + ( src[i] - '0'); // on somme des positifs
diviseur = diviseur*10;
i++;
cout << "+";
}
return partieEntiere + partieDecimale / diviseur ;
}
/**
* programme principal
*/
int main ()
{
cout << "une * représente une iteration dans la methode du sujet." << endl;
cout << "une + représente une iteration dans la methode optimisée." << endl;
cout << endl;
cout << "[ iterations résultat donnée méthode]" << endl;
cout << "\t" << convertirChaineVersFloat( "3.14" ) << "\t 3.14 \t s" << endl;
cout << "\t" << convertirChaineVersFloat2( "3.14" ) << "\t 3.14 \t o" << endl;
cout << endl;
cout << "\t" << convertirChaineVersFloat( "0.14" ) << "\t 0.14 \t s" << endl;
cout << "\t" << convertirChaineVersFloat2( "0.14" ) << "\t 0.14 \t o" << endl;
cout << endl;
cout << "\t" << convertirChaineVersFloat( ".19" ) << "\t .19 \t s" << endl;
cout << "\t" << convertirChaineVersFloat2( ".19" ) << "\t .19 \t o" << endl;
cout << endl;
cout << "\t" << convertirChaineVersFloat( "." ) << "\t . \t s" << endl;
cout << "\t" << convertirChaineVersFloat2( "." ) << "\t . \t o" <<endl;
cout << endl;
cout << "\t" << convertirChaineVersFloat( "21234" ) << "\t 21234 \t s" <<endl;
cout << "\t" << convertirChaineVersFloat2( "21234" ) << "\t 21234 \t o" <<endl;
cout << endl;
cout << "\t" << convertirChaineVersFloat( "569318.5995" ) << "\t 569318.5995 \t s" <<endl;
cout << "\t" << convertirChaineVersFloat2( "569318.5995" ) << "\t 569318.5995 \t o" <<endl;
cout << endl;
cout << "\t" << convertirChaineVersFloat( "0.599577" ) << "\t 0.599577 \t s" <<endl;
cout << "\t" << convertirChaineVersFloat2( "0.599577" ) << "\t 0.599577 \t o" <<endl;
cout << endl;
cout << "que remarque t'on pour 569318.5995? pourquoi? comment déterminerez vous ou à lieu l'erreur?" << endl << endl;
return 0;
}