Bienvenue invité ( Connexion | Inscription )

 
Reply to this topicStart new topic
> [Aide] Programme C++ [Aide]
Darknight670
posté 20 Nov 2007, 18:24
Message #1





Groupe : Inscrit
Messages : 76
Inscrit : 30-Sep-07
Lieu : Meudon, (Paris)
Membre n° 1205



Bonjour,

je débute vraiment en programmation C++ donc je crée des petits programmes pour m'entraîner. Or j'essaye de calculer Pi a l'aide la méthode Monte Carlo (pour maîtriser les rand () ) et mon programme ne marche pas ... mais sans erreurs apparentes de compilation...

CODE
##include <iostream>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <iomanip>

using namespace std ;

int main ()
{
cout << "Simulation de Pi\n" ;
cout << "Entrez un nombre etier de simulations a effectuer.\n" ;

int N ;
cin >> N ;

double X ;
double Y ;
double R ;
int M ;
int S ;

srand ( time (0) ) ;


while ( S < N )
{
X = 2 * rand () - 1 ;
Y = 2 * rand () - 1 ;

R = sqrt ( X*X + Y*Y ) ;

if ( R <= 1 )
{
M++ ;
S++ ;
}
else
{
S++ ;
}

}
cout << "Approximation de Pi: \n" << 4 * ( M/N ) << setprecision (5) ;
return 0;
}



EDIT 1 : Dans le debugger ça donne ca :

CODE
[Session started at 2007-11-20 18:25:20 +0100.]
Simulation de Pi
Entrez un nombre etier de simulations a effectuer.
10
Approximation de Pi:
-6.4226e+08
The Debugger has exited with status 0.


Qu'est ce qui ne va pas?
Et que me conseillez vous pour apprendre a maîtriser le C++? ( Livres , sites ET idées de projets etc... )

Ce message a été modifié par Darknight670 - 20 Nov 2007, 18:44.
Go to the top of the page
 
+Quote Post
Gamoul
posté 20 Nov 2007, 18:33
Message #2


L'évangéliste


Groupe : Admin Technique
Messages : 12112
Inscrit : 9-Nov-05
Lieu : Brest
Membre n° 354



Je ne connais pas l'algorithme que tu utilises donc je sais pas si tu l'as correctement programmé, mais je vois un problème car tu n'initialise pas ta variable S à 0 au début.
Go to the top of the page
 
+Quote Post
Darknight670
posté 20 Nov 2007, 18:46
Message #3





Groupe : Inscrit
Messages : 76
Inscrit : 30-Sep-07
Lieu : Meudon, (Paris)
Membre n° 1205



CITATION(Gamoul @ 20 Nov 2007, 18:33) *
Je ne connais pas l'algorithme que tu utilises donc je sais pas si tu l'as correctement programmé, mais je vois un problème car tu n'initialise pas ta variable S à 0 au début.


Je l'initialise en même temps que les autre au début de main () ce n'est pas bon?

CODE
double X ;
double Y ;
double R ;
int M ;
int S ;


Ce message a été modifié par Darknight670 - 20 Nov 2007, 18:47.
Go to the top of the page
 
+Quote Post
atarxerxes
posté 20 Nov 2007, 19:02
Message #4


Marathon Man


Groupe : Ancien de la Team
Messages : 10953
Inscrit : 20-Nov-04
Lieu : Paris, XIe
Membre n° 160



Ca c'est la déclaration, pas l'initialisation de sa valeur. En C tu n'es pas assuré de la valeur initiale d'une variable si tu ne le mets pas toi-même (par un S = 0; )


--------------------
Ordis: iPad 2 16Go 3G ; MacbookAir 11" Core i7 2GHz 8 Go RAM SSD128Go + Dell 2405FPW; Mini C2D2.0GHz media center / Accessoires: Wii , XBox360, PS3, 3DS, iPhone 4 / Télé: Numericable HD Box -> Samsung LE32R51B + Denon AVR-3808 + 5.0 Triangle
About.me
"Je n'ai jamais aimé que moi / Et je reste sans lendemain", H.F. Thiéfaine
"Reality is that which, when you stop believing in it, doesn’t go away", Philip K. Dick
Go to the top of the page
 
+Quote Post
DBSor
posté 20 Nov 2007, 19:25
Message #5


Tabouret magique


Groupe : Admin
Messages : 7740
Inscrit : 16-Jan-05
Lieu : Sous le tas de moules
Membre n° 212
Section(s) : FPS



Utilise le debugger, tu pourras suivre instruction par instruction ce que fait ton programme, c'est très instructif wink.gif


--------------------
"Je sais que j'plais pas à tout le monde ! Mais quand je vois à qui j'plais pas, j'me demande si ça me dérange vraiment"
Dikkenek - Olivier Van Hoofstadt, Olivier Legrain - 2006

Message permanent: Je suis à la ramasse sur tous les anniversaires, désolé
Go to the top of the page
 
+Quote Post
Acid
posté 20 Nov 2007, 21:00
Message #6


Dr Mouse


Groupe : Membre
Messages : 2986
Inscrit : 19-May-06
Lieu : Béziers
Membre n° 572



0) Initialisation de S indiqué par Gamoul
2) Le probleme:
Pour la methode de monte carlo il faut avoir des nombres dans [O;1] la fonction rand() retourne des nombre entre 0 et RAND_MAX (grand entier)
Pour avoir un rand entre 0 et 1 faire:
CODE
rand() / ((double) RAND_MAX);
3) test <=1 plutot <1 ici par rapport à l'algorithme utilisé (mais ce ne doit pas etre si important ici)
4) Sinon pour la forme:
etier => entier
pour le if j'ecrirai
CODE
if ( R < 1 )
      {M++;
      }
S++;
5) Test avec debugger (ou affichage des variables au minimum) indiqué par dbsor
6) La fonction rand n'est pas terrible, pour une utilisation dans le cadre d'algo du type Monte carlo on utilise une fonction plus sophistiquée ( loi uniforme, loi normale ...)

@+

Ce message a été modifié par appleseed - 21 Nov 2007, 08:52.


--------------------
Bb
Go to the top of the page
 
+Quote Post
Darknight670
posté 22 Nov 2007, 10:46
Message #7





Groupe : Inscrit
Messages : 76
Inscrit : 30-Sep-07
Lieu : Meudon, (Paris)
Membre n° 1205



CITATION(appleseed @ 20 Nov 2007, 21:00) *
0) Initialisation de S indiqué par Gamoul
2) Le probleme:
Pour la methode de monte carlo il faut avoir des nombres dans [O;1] la fonction rand() retourne des nombre entre 0 et RAND_MAX (grand entier)
Pour avoir un rand entre 0 et 1 faire:
CODE
rand() / ((double) RAND_MAX);
3) test <=1 plutot <1 ici par rapport à l'algorithme utilisé (mais ce ne doit pas etre si important ici)
4) Sinon pour la forme:
etier => entier
pour le if j'ecrirai
CODE
if ( R < 1 )
      {M++;
      }
S++;
5) Test avec debugger (ou affichage des variables au minimum) indiqué par dbsor
6) La fonction rand n'est pas terrible, pour une utilisation dans le cadre d'algo du type Monte carlo on utilise une fonction plus sophistiquée ( loi uniforme, loi normale ...)

@+


2/ RAND_MAX doit être défini? ou pas besoin ?
4/ si on ne fait que if ( R < 1 ) il considerera que les pts a 1 cm du centre ne sont pas dans le cercle non? alors que si (d'après moi...)?

Mais merci a vous tous Gamoul , Appleseed et " Celui qui a un nom imprononçable" Aterxexes
Go to the top of the page
 
+Quote Post
macgic
posté 22 Nov 2007, 11:15
Message #8





Groupe : Membre
Messages : 360
Inscrit : 22-Jun-04
Lieu : A coté de Lille le WE, à coté de Paris la semaine...
Membre n° 101
Section(s) : JdS



Je ne suis plus certain mais il me semblait que la fonction rand renvoyait des réels entre 0 et 1. En tout cas, dans mes programmes, je n'ai jamais défini de RAND_MAX.

Pour ce qui est du point 4, effectivement, les points juste l'extérieur du disque ne sont pas pris en compte avec R <1. Ceci dit, probabilistement, c'est un événement de mesure nulle (donc proba que ça arrive = 0, du moins dans la théorie) donc ça ne changera rien du tout au résultat.


--------------------
Go to the top of the page
 
+Quote Post
Acid
posté 22 Nov 2007, 15:17
Message #9


Dr Mouse


Groupe : Membre
Messages : 2986
Inscrit : 19-May-06
Lieu : Béziers
Membre n° 572



Exemple rand_max avec google (j'ai de la chance).


--------------------
Bb
Go to the top of the page
 
+Quote Post
Darknight670
posté 22 Nov 2007, 18:44
Message #10





Groupe : Inscrit
Messages : 76
Inscrit : 30-Sep-07
Lieu : Meudon, (Paris)
Membre n° 1205



Désolé de vous embêter mais voila une autre de mes questions...
CODE
int main ( int argc , char * argv[] )
Cette ligne de code permet de récupérer des arguments mais si j'exécute mon programme comme ça :
CODE
monprogg.app -10000
Comment faire pour récupérer l'argument 10000? car
CODE
int Truc = argv [1]
ca ne peut pas marcher a cause des problèmes de conversions....

Ce message a été modifié par Darknight670 - 22 Nov 2007, 18:45.
Go to the top of the page
 
+Quote Post
Acid
posté 22 Nov 2007, 19:27
Message #11


Dr Mouse


Groupe : Membre
Messages : 2986
Inscrit : 19-May-06
Lieu : Béziers
Membre n° 572



Comme tu l'indiques ici: int main ( int argc , char * argv[] ) les arguments sont des chaines de caracteres.
Si tu essayes cela: int Truc = argv [1] tu essaye de convertir directement une chaîne en un entier => message d'erreur.
La chaine 12 est code en memoire par le code ascii du 1 (sur un octet : 31) puis le code ascii du 2 (sur un octet:32) puis un code ascii 00
Ce qui donne en hexa: 31 32 00
L'entier 12 est codé en memoire par 00 00 00 OC
Comme tu peux le voir cela ne se ressemble pas il faut donc lancer une fonction pour faire la conversion:
int n = atoi(argv[1]);

@+

Ce message a été modifié par appleseed - 22 Nov 2007, 19:33.


--------------------
Bb
Go to the top of the page
 
+Quote Post
macgic
posté 22 Nov 2007, 19:30
Message #12





Groupe : Membre
Messages : 360
Inscrit : 22-Jun-04
Lieu : A coté de Lille le WE, à coté de Paris la semaine...
Membre n° 101
Section(s) : JdS



réponse éclair car je ne suis pas du tout sûr de moi (je n'utilise jamais argv, je mets toujours un cout et un cin pour entrer les paramètres tongue.gif ) mais il me semble que c'est argv[0] (premier élement du tableau).

Et est-ce que ça ne marche pas en castant la valeur (quitte à faire une gestion d'exception si soucis dans la conversion) ?
int Truc = (int) argv[0];


--------------------
Go to the top of the page
 
+Quote Post
Acid
posté 22 Nov 2007, 19:35
Message #13


Dr Mouse


Groupe : Membre
Messages : 2986
Inscrit : 19-May-06
Lieu : Béziers
Membre n° 572



CITATION(macgic @ 22 Nov 2007, 19:30) *
réponse éclair car je ne suis pas du tout sûr de moi (je n'utilise jamais argv, je mets toujours un cout et un cin pour entrer les paramètres tongue.gif ) mais il me semble que c'est argv[0] (premier élement du tableau).

Et est-ce que ça ne marche pas en castant la valeur (quitte à faire une gestion d'exception si soucis dans la conversion) ?
int Truc = (int) argv[0];


non, les casts sont des changements de representation entre nombre et aussi sur des adresses memoire (void* char* ...). Ici cela ne marchera pas...
Si tu as des doutes sur les arguments, le mieux pour comprendre est de faire afficher tous les arguments, argc te donne le nombre de ces arguments.
CODE
int i;
for (i =0;i<argc;i++)
printf("%d %s\n",i,argv[i]);

@+

Ce message a été modifié par appleseed - 22 Nov 2007, 19:38.


--------------------
Bb
Go to the top of the page
 
+Quote Post
Darknight670
posté 25 Nov 2007, 11:16
Message #14





Groupe : Inscrit
Messages : 76
Inscrit : 30-Sep-07
Lieu : Meudon, (Paris)
Membre n° 1205



Merci a tous j'ai réussi a le faire marcher ! Je ne sais pas pourquoi ça ne marchais pas donc je ne sais pas pourquoi il marche maintenant ... ( erreur de chiffres significatifs je crois...)
CODE
/* Importation de bibliothèques */
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <stdio.h>

using namespace std ;

int iChoix = 0 ;
/* -------------------------------------------------------------------------------------------------------------------- */
int iAlea ( void ) // Cette fonction genere un nb aleatoire....
{

static int first = 0;

if (first == 0)
{

srand (time ( NULL ) );
first = 1;

}
return ( rand () );
}
/* -------------------------------------------------------------------------------------------------------------------- */
double dExact( long int iPrecision )
{
/* Définition des variables */
double dPi = 0 ;
bool bAddition = true ;
long int liDiviseur = 3 ;
long int liCompteur = 0 ;


dPi = 1 - 1/ (double) liDiviseur;

cout << "Calcul de Pi en cours...\n"; /* Affichage d'un message en attendant que */
cout << "Svp patienter...\n\n" ; /* Pi soit calculé. */

/* Calcul de Pi */
do

{
liDiviseur = liDiviseur + 2;
if (bAddition == true)
{
dPi = dPi + 1/ (double) liDiviseur;
bAddition = false;
}

else

{
dPi = dPi - 1/ (double) liDiviseur;
bAddition = true;
}

liCompteur++;
}
while ( liCompteur <= iPrecision);

/* Affichage du résultat */
dPi = dPi * 4;
return dPi ;
}

/* -------------------------------------------------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------------------------------------------------- */

float fSimulationPi ( int iIteration )
{
float fCoordonneeX ;
float fCoordonneeY ;
float fLongueur ;
int iSimulation = 0 ;
int iPointCercle = 0 ;
int iPointTotal = 0 ;

while ( iSimulation <= iIteration )
{

iAlea () ;
fCoordonneeX = 2 * rand () / ( RAND_MAX + 1.0 ) ;
iAlea () ;
fCoordonneeY = 2 * rand () / ( RAND_MAX + 1.0 ) ;

fLongueur = sqrt (fCoordonneeX*fCoordonneeX + fCoordonneeY*fCoordonneeY) ;

if ( fLongueur < 1 )

{
iPointCercle++ ;
}

iSimulation++ ;
iPointTotal++ ;
}
return ( 4.00 * iPointCercle / iPointTotal ) ;
}

/* -------------------------------------------------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------------------------------------------------- */

int main ()
{

if ( iChoix == 0 )
{
cout << " ****************************\n" ;
cout << " * *\n" ;
cout << " * Pi Calculator *\n" ;
cout << " * Cree par Darknight670 *\n" ;
cout << " * Le 25/11/07 *\n" ;
cout << " * *\n" ;
cout << " ****************************\n" ;
}

cout << endl ;
cout << "Comment voulez vous calculez Pi?\n" ;
cout << "1.Par la methode Monte Carlo\n";
cout << "2.Grace au Theoreme de Leibniz\n" ;
cout << "0.Quitter\n" ;

cin >> iChoix ;

if ( iChoix == 1 )
{
cout << endl ;
cout << "Entrez un nombre de simulations a effectuer\n" ;

int iIteration ;
cin >> iIteration ;

cout << "Pi vaut : " << fSimulationPi ( iIteration ) ;
cout << endl ;

main () ;
}

if ( iChoix == 2 )
{

cout << endl ;
cout << "Entrez une precision de calcul\n" ;

int iPrecision ;
cin >> iPrecision ;

cout << "Pi vaut : " << dExact ( iPrecision ) ;
cout << endl;

main () ;

}

if ( iChoix == 0 )
{

cout << " Merci et au revoir!\n" ;
return 0 ;

}

return 1 ;
}

/* -------------------------------------------------------------------------------------------------------------------- */



Merci encore a tous
Go to the top of the page
 
+Quote Post
Acid
posté 25 Nov 2007, 12:15
Message #15


Dr Mouse


Groupe : Membre
Messages : 2986
Inscrit : 19-May-06
Lieu : Béziers
Membre n° 572



CITATION(Darknight670 @ 25 Nov 2007, 11:16) *
Merci a tous j'ai réussi a le faire marcher ! Je ne sais pas pourquoi ça ne marchais pas donc je ne sais pas pourquoi il marche maintenant ... ( erreur de chiffres significatifs je crois...)

L'erreur provenait du fait que tu retournais un rand qui n'etait pas entre 0 et 1.
Au niveau de ton source:
La fonction Ilea ne sert à rien en fait.
Tu n'utilises pas le resultat retourne
Tu utilises une variable locale qui est mise à 0 puis testée => la fonction fait un srand chaque fois qu'elle est lancee..
Bref non utile.
=> enlever cette fonction et l'appel de cette fonction et mettre srand (time ( NULL ) ); en debut de ton programme.
et tu pourrais faire une fonction rand01 qui retourne une valeur entre 0 et 1.
Pour ne faire le srand qu'une fois comme dans ton code, c'est aussi possible mais dans ce cas il faut faire une variable globale (pas terrible de mon point de vue) toutefois voici une solution basée sur ton code:
CODE
static int first = 0;// En global
double rand01 ( void ) // Cette fonction genere un nb aleatoire....
{
if (first == 0)
{
srand (time ( NULL ) );
first = 1;
}
return rand () / ( RAND_MAX + 1.0 );
}
Ensuite modifies ton programme
CODE
iAlea ();
fCoordonneeX = 2 * rand () / ( RAND_MAX + 1.0 );
iAlea ();
fCoordonneeY = 2 * rand () / ( RAND_MAX + 1.0 );
Devient
CODE
fCoordonneeX = 2 * rand01();
fCoordonneeY = 2 * rand01();
@+

Ce message a été modifié par appleseed - 26 Nov 2007, 09:42.


--------------------
Bb
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



RSS Version bas débit Nous sommes le : 27 May 2024 - 13:14