|
|
|
|
Bonjour,
je suis en train d'essayer de programmer le calcul d'une racine carrée approché au moyen de l'algorithme de Heron d'Alexandrie en C, le tout en récursif.
J'ai beau me creusé la tête depuis quelques heures le seul code que j'arrive à trouver est celui-ci dessous qui, comme vous vous en doutez, ne marche pas. Je me sis donc résolut à venir demander de l'aide ici, mais aussi et surtout des explication et aide pour que je puisse me débrouiller à l'avenir.
Merci d'avance.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float racine_carree(int a, int n)
{
float x,b,z;
x=1;
while((x*x)<a)
{
x=x+1;
}
b=x;
if((x*x)==a)
{
return x;
}
else
{
if(n==0)
{
return a;
}
else
{
if(n==1)
{
x=(1/2)*(x+(a/x));
return x;
}
else
{
z=(1/2)*((racine_carree(b,n-1))+(a/(racine_carree(b,n-1))));
printf("Voila x= %0.4f \t pour l'etape n= %d \n",b,n);
return z;
}
}
}
}
int main(){
int a,n;
float x;
printf("rentrez le nombre :");
scanf("%d",&a);
printf("\n rentrez le nombre d'iteration :");
scanf("%d",&n);
x=racine_carree(a,n);
printf("voila la racine carree %0.4f \t",x);
printf("la racine carree trouvee par sqrt est: %f",sqrt(a));
}L'erreur que je vois est que tu divise un int par un float, et ceci peut te donner des resultats faux, donc pour eviter ce genre d'erreur, je te conseil de tout mettre en float, ou alors de convertir lorsqu'il le faut tes int en float. de meme que lorsque tu refais appelle a ta fonction, elle prend un int en entré, et toi tu lui rentre un float.
|
En effet, merci de la remarque, voila le code une fois cela corrigé (j'ai aussi changé le nom des variable pour le rendre peut être un peu plus lisible ^^) :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float racine_carree(float chiffre, int iteration)
{
float CasBase,CasUn,Racine,b;
CasBase=1.0;
while((CasBase*CasBase)<chiffre)
{
CasBase=CasBase+1.0;
}
b=CasBase;
if((CasBase*CasBase)==chiffre)
{
return CasBase;
}
else
{
if(iteration==0)
{
return chiffre;
}
else
{
if(iteration==1)
{
CasUn=(1.0/2.0)*(CasBase+(chiffre/CasBase));
return CasUn;
}
else
{
Racine=(1.0/2.0)*((racine_carree(b,iteration-1))+(chiffre/(racine_carree(b,iteration-1))));
printf("Voila x= %0.4f \t pour l'etape n= %d \n",b,iteration);
return Racine;
}
}
}
}
int main(){
int etape;
float num,racine;
printf("rentrez le nombre :");
scanf("%f",&num);
printf("\n rentrez le nombre d'iteration :");
scanf("%d",&etape);
racine=racine_carree(num,etape);
printf("voila la racine carree %0.4f \t",racine);
printf("la racine carree trouvee par sqrt est: %f",sqrt(num));
}
|
Salut,
double racine_carree(const double chiffre, double xn, int iteration){
if(iteration==0)
return xn;
else
return racine_carree(chiffre,0.5*(xn+chiffre/xn),iteration-1);
}
Google is your friend |
Merci beaucoup pour ton coup de main fiddy, grâce à ta solution mon programme marche (j'ai mis le code ci-dessous, ça peut toujours aider si quelqu'un ce retrouve dans la même galère que moi ^^). Pour info, la première partie de la fonction, qui ce retrouve maintenant dans le main, sert juste a optimiser le programme. Enfin, ma consigne exacte été de " Écrire une fonction prenant en paramètre un réel a et un entier n, qui calcule et affiche les n premiers termes de la suite. On affichera également la racine carrée de a, à titre de comparaison (on utilisera pour cela la fonction sqrt de la bibliothèque math.h)." or, avec cette solution j'ai 3 paramètres :s donc si quelqu'un a une idée je suis preneur parce que je vois pas comment faire ...
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double racine_carree(double chiffre, int iteration, double xn)
{
double CasUn,Racine;
if(iteration==0){
return xn;
}
else{
if(iteration==1){
CasUn=(1.0/2.0)*(xn+(chiffre/xn));
return CasUn;
}
else
{
Racine=racine_carree(chiffre,iteration-1,(0.5*(xn+(chiffre)/xn)));
printf("Voila x%d= %0.4lf \t pour l'etape n= %d \n",iteration,xn,iteration);
return Racine;
}
}
}
int main(){
int etape;
float num, CasBase,b;
double racine;
printf("rentrez le nombre :");
scanf("%f",&num);
printf("\n rentrez le nombre d'iteration :");
scanf("%d",&etape);
CasBase=0.0;
if(num==0){
b=0;
}
else{
do{
CasBase=CasBase+1.0;
}while((CasBase*CasBase)<num-1);
b=CasBase;
}
if((b*b)==num){
printf("La racine carree de %.0f est %.0f , resultat trouve apres 0 iteration.\t",num,b);
}
else{
racine=racine_carree(num,etape,b);
printf("Voila la racine carree %lf . \t",racine);
}
printf("La racine carree trouvee par sqrt est: %lf \n",sqrt(num));
system("PAUSE");
}
|
Utilise plutôt des double, c'est mieux ;-))). Ou alors utilise fsqrt au lieu de sqrt pour renvoyer un float.
|
Voila mon code après modification via tes conseils, qu'en pense tu cela a l'air de marcher et de remplir les conditions de mon énoncé, si tu vois des bugs hésite pas a me le signalé, en tout cas merci beaucoup, encore.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static float chiffre;
double racine_carree(double xn, int iteration)
{
double CasUn,Racine;
if(iteration==0){
return xn;
}
else{
if(iteration==1){
CasUn=(1.0/2.0)*(xn+(chiffre/xn));
return CasUn;
}
else
{
Racine=racine_carree((0.5*(xn+(chiffre)/xn)),iteration-1);
printf("Voila x%d= %0.4lf \t pour l'etape n= %d \n",iteration,xn,iteration);
return Racine;
}
}
}
int main(){
int etape;
float CasBase,b;
double racine;
printf("rentrez le nombre :");
scanf("%f",&chiffre);
printf("\n rentrez le nombre d'iteration :");
scanf("%d",&etape);
CasBase=0.0;
if(chiffre==0){
b=0;
}
else{
if(fabs(chiffre-2.0)<1e-5){
CasBase=1;
}
else{
do{
CasBase=CasBase+1.0;
}while((CasBase*CasBase)<chiffre-1);
b=CasBase;
}
}
if(fabs((b*b)-chiffre)<1e-5){
printf("La racine carree de %.0f est %.0f , resultat trouve apres 0 iteration.\t",chiffre,b);
}
else{
racine=racine_carree(b,etape);
printf("Voila la racine carree %lf . \t",racine);
}
printf("La racine carree trouvee par sqrt est: %lf \n",sqrt(chiffre));
system("PAUSE");
return 0;
}
|
Mets tout en double plutôt ;-))). Sauf cas très particulier, le float est moins bien que le double.
scanf("%lf",&chiffre);
printf("Voila la racine carree %f . \t",racine);
printf("La racine carree trouvee par sqrt est: %f \n",sqrt(chiffre));
Mets le prototype int main(void). Remarques facultatives mais conseillées ^^: Après, tu peux simplifier l'écriture de code en ajoutant des fonctions statiques (par exemple pour le calcul de b. Tu n'as pas besoin de créer une variable pour la retourner juste après. return (0.5)*(xn+chiffre/xn); /*pas besoin de CasUn*/ Et pour finir, rajoute des commentaires (vivement conseillés, surtout si c'est noté par le prof ^^). Cdlt Google is your friend |
Voilà le programme final (normalement), j'ai essayer de travailler la mise en page source/programme et je n'ai pas relevé de bugs particulier, j'ai aussi essayé d'appliquer tes bons conseils a tout mon programme :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//Déclaration de variable globale
static double chiffre;
static int etape;
//Déclaration de la fonction
double racine_carree(double xn, int iteration)
{
double Racine;
if(iteration==0){
return xn; //Cas de base de la fonction
}
else{
printf("\t%d)\t Pour l'etape n= %d \n",etape-iteration,etape-iteration); //Affiche l'étape de la suite mathématique
printf("\t|____________________________________________|\n"); //Mise en Page
printf("\t\t voila x%d= %0.15lf \n ",etape-iteration,xn); //Affiche la valeur de x(n)
printf("\t|____________________________________________|\n"); //Mise en page
return racine_carree((0.5*(xn+(chiffre)/xn)),iteration-1); //Retourne la valeur de la racine carrée grace à un appel récursif
}
}
//Déclaration du Main
int main(){
double racine,CasBase,b;
printf("rentrez le nombre :");
scanf("%lf",&chiffre); //Saisie du chiffre dont l'utilisateur veut la racine carrée
printf("\n rentrez le nombre d'iteration :");
scanf("%d",&etape); //Saisie du nombre d'itération a produire (précision)
system("echo,Pour voir le calcul de la racine carree selon la methode de Heron d'Alexandrie "); //Mise en page
system("PAUSE"); //Mise en page
CasBase=0.0; //initialisation de CasBase
if(chiffre==0){
b=0; //cas particulier 1
}
else{
if(fabs(chiffre-2.0)<1e-5){
b=1; //cas particulier 2
}
else{
do{
CasBase=CasBase+1.0;
}while((CasBase*CasBase)<chiffre-1);
b=CasBase; //valeur approché par default de la racine carrée recherché pour optimiser le programme
}
}
if(fabs((b*b)-chiffre)<1e-5){
printf("La racine carree de %.0f est %.0f , resultat trouve apres 0 iteration.\n",chiffre,b); //cas particulier où la racine carré est un entier naturel
}
else{
printf("\t_____________________________________________\n"); //Mise en page
racine=racine_carree(b,etape); //Appel de la fonction racine carrée
printf("La racine carree de %lf, d'apres mon programme, est donc %lf. \n",chiffre,racine); //Affichage de la racine carrée trouvée par la fonction racine_carree
}
printf("La racine carree trouvee par sqrt est: %lf. \n",sqrt(chiffre)); //Affichage de la racine carrée trouvée par la fonction sqrt() de la bibliothèque math.h
system("PAUSE");
return 0;
}
Merci encore pour tout, et je mettrai en résolut demain si personne n'y a relevé de bug entre temps :).
|
En effet certaine de tes remarques été passé à la trappes ^^" désolé, par contre la variable etape je l'ai déclarée en globale même si je sais que c'est très déconseillé pour un soucis de mise en page, pour ce qui est des commentaires, j'arrive jamais à savoir ce qui vaux le coup d'etre commenté ou pas -_-".
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//Déclaration de variable globale
static double chiffre;
static int etape;
/*Déclaration de la fonction
Cette fonction sert à appliquer la formule de Heron d'Alexandrie pour le calcul d'une racine carrée
xn: Reel correspondant au cas x0 trouver grâce a la structure dans le main
qui donne une approximation par defaut de la racine carrée du "chiffre"
*/
double racine_carree(double xn, int iteration)
{
double Racine;
if(iteration==0){
return xn;
}
else{
printf("\t%d)\t Pour l'etape n= %d \n",etape-iteration,etape-iteration);
printf("\t|____________________________________________|\n");
printf("\t\t voila x%d= %0.15lf \n ",etape-iteration,xn);
printf("\t|____________________________________________|\n");
return racine_carree((0.5*(xn+(chiffre)/xn)),iteration-1);
}
}
//Déclaration du Main
int main(void){
double racine,CasBase,b;
printf("rentrez le nombre dont vous voulez connaitre la racine carree:");
scanf("%lf",&chiffre);
printf("\n rentrez le nombre d'iteration (nombre entier):");
scanf("%d",&etape);
system("echo,Pour voir le calcul de la racine carree selon la methode de Heron d'Alexandrie ");
system("PAUSE");
CasBase=0.0;
if(chiffre==0.0){
b=0.0;
}
else{
if(fabs(chiffre-2.0)<1e-5){
b=1.0;
}
else{
do{
CasBase=CasBase+1.0;
}while((CasBase*CasBase)<chiffre-1);
b=CasBase;
}
}
if(fabs((b*b)-chiffre)<1e-5){
printf("La racine carree de %.0f est %.0f , resultat trouve apres 0 iteration.\n",chiffre,b);
}
else{
printf("\t_____________________________________________\n");
racine=racine_carree(b,etape);
printf("La racine carree de %f, d'apres mon programme, est donc %f. \n",chiffre,racine);
}
printf("La racine carree trouvee par sqrt est: %lf. \n",sqrt(chiffre));
system("PAUSE");
return 0;
}
|
J'ai corrigé le dernier lf qui m'avait échappé :)
/*
------------------------------------------------------------------------------------------------------------
--Nom: ************* Prenom: *********** --
--But du programme: Calcul d'une racine carrée d'après l'algorithme de Heron d'Alexandrie --
--Lic 1 Info ****** : Devoir --
--Date de creation: Mardi 14 Avril 2009 --
--Date de modification: --
--Raison de la modification: --
------------------------------------------------------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//Déclaration de variable globale
static double chiffre;
static int etape;
//Déclaration de la fonction
/*Cette fonction sert à appliquer la formule de Heron d'Alexandrie pour le calcul d'une racine carrée
xn: Reel correspondant au cas x0 trouver grâce a la structure dans le main
qui donne une approximation par defaut de la racine carrée du "chiffre"
*/
double racine_carree(double xn, int iteration)
{
double Racine;
if(iteration==0){
return xn;
}
else{
printf("\t%d)\t Pour l'etape n= %d \n",etape-iteration,etape-iteration);
printf("\t|____________________________________________|\n");
printf("\t\t voila x%d= %0.15lf \n ",etape-iteration,xn);
printf("\t|____________________________________________|\n");
return racine_carree((0.5*(xn+(chiffre)/xn)),iteration-1);
}
}
//Déclaration du Main
int main(void){
int a;
double racine,CasBase,b;
printf("rentrez le nombre dont vous voulez connaitre la racine carree:");
scanf("%lf",&chiffre);
printf("\n rentrez le nombre d'iteration (nombre entier):");
scanf("%d",&etape);
printf("Pour voir le calcul de la racine carree selon la methode de Heron d'Alexandrie ");
system("PAUSE");
CasBase=0.0;
if(chiffre==0.0){
b=0.0;
}
else{
if(fabs(chiffre-2.0)<1e-5){
b=1.0;
}
else{
do{
CasBase=CasBase+1.0;
}while((CasBase*CasBase)<chiffre-1);
b=CasBase;
}
}
if(fabs((b*b)-chiffre)<1e-5){
printf("La racine carree de %.0f est %.0f , resultat trouve apres 0 iteration.\n",chiffre,b);
}
else{
printf("\t______________________________________________\n");
racine=racine_carree(b,etape);
printf("La racine carree de %f, d'apres mon programme, est donc %f. \n",chiffre,racine);
}
printf("La racine carree trouvee par sqrt est: %f. \n",sqrt(chiffre));
system("PAUSE");
return 0;
}
|