[Aide] Programme C++ [Aide] |
Bienvenue invité ( Connexion | Inscription )
[Aide] Programme C++ [Aide] |
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. |
|
|
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.
|
|
|
20 Nov 2007, 18:46
Message
#3
|
|
Groupe : Inscrit Messages : 76 Inscrit : 30-Sep-07 Lieu : Meudon, (Paris) Membre n° 1205 |
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. |
|
|
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 |
|
|
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
-------------------- "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é |
|
|
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 ) 5) Test avec debugger (ou affichage des variables au minimum) indiqué par dbsor{M++; } S++; 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
|
|
|
22 Nov 2007, 10:46
Message
#7
|
|
Groupe : Inscrit Messages : 76 Inscrit : 30-Sep-07 Lieu : Meudon, (Paris) Membre n° 1205 |
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 ) 5) Test avec debugger (ou affichage des variables au minimum) indiqué par dbsor{M++; } S++; 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 |
|
|
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. -------------------- |
|
|
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
|
|
|
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. |
|
|
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
|
|
|
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 ) 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]; -------------------- |
|
|
22 Nov 2007, 19:35
Message
#13
|
|
Dr Mouse Groupe : Membre Messages : 2986 Inscrit : 19-May-06 Lieu : Béziers Membre n° 572 |
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 ) 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
|
|
|
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 |
|
|
25 Nov 2007, 12:15
Message
#15
|
|
Dr Mouse Groupe : Membre Messages : 2986 Inscrit : 19-May-06 Lieu : Béziers Membre n° 572 |
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 Ensuite modifies ton programmedouble rand01 ( void ) // Cette fonction genere un nb aleatoire.... { if (first == 0) { srand (time ( NULL ) ); first = 1; } return rand () / ( RAND_MAX + 1.0 ); } CODE iAlea (); DevientfCoordonneeX = 2 * rand () / ( RAND_MAX + 1.0 ); iAlea (); fCoordonneeY = 2 * rand () / ( RAND_MAX + 1.0 ); CODE fCoordonneeX = 2 * rand01(); @+
fCoordonneeY = 2 * rand01(); Ce message a été modifié par appleseed - 26 Nov 2007, 09:42. -------------------- Bb
|
|
|
Version bas débit | Nous sommes le : 27 May 2024 - 13:14 |