IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Petit programme en C [Second degré]


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Petit programme en C [Second degré]
    Voila, je suis un débutant en C (je viens de finir le premier chapitre de "Méthodologie de la programmation en C" de Jean Pierre Baquelaire pour ceux qui connaissent et je viens de créer un programme en C qui résout les équations du second degré avec les valeurs exactes et approchées, dans le complexes et les réels. Mon programme fonctionne parfaitement mais il y a quelques lourdeurs. Donc ceux qui peuvent répondre à mes questions ci apres, ce serait sympa :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <float.h>
     
    static int racine_delta(int delta);
    static void usage(char *);
     
     
     
    int
    main(int argc, char *argv[])
    {
    	if (argc != 4)
    		usage(argv[0]);
    	int a = floor(atof(argv[1]));
    	if (a == 0);
    		usage(argv[0]);
    	int b = floor(atof(argv[2]));
    	int c = floor(atoi(argv[3]));
     
    	int delta = (b * b) - (4 * a * c);
     
    	if (delta != 0)
    	{
    		printf("Deux solutions %s :\n\n", (delta < 0) ? "complexes et conjuguees" : "reelles");
    		int d = printf("%d + %s(%d * rac(%d))\n", -b, (delta < 0) ? "i" : "", racine_delta(delta), abs(delta / (racine_delta(delta) * racine_delta(delta))));
    		int e;
    		for (e = 1; e <= d; e++)
    		{
    			printf("-");
    		}
    		if (delta > 0)
    		{
    			printf(" = %f\n", (-b + sqrt(delta)) / (2 * a));
    		}
    		else if (delta < 0)
    		{
    			printf(" = %f + i * %f\n", ((float)-b/(2*a)), (sqrt(abs(delta)))/(2 * a));
    		}
    		printf("%d\n\n", 2 * a);
     
    		d = printf("%d - %s(%d * rac(%d))\n", -b, (delta < 0) ? "i" : "", racine_delta(delta), abs(delta / (racine_delta(delta) * racine_delta(delta))));
    		for (e = 1; e <= d; e++)
    		{
    			printf("-");
    		}
    		if (delta > 0)
    		{
    			printf(" = %f\n", (-b + sqrt(delta)) / (2 * a));
    		}
    		else if (delta < 0)
    		{
    			printf(" = %f - i * %f\n", ((float)-b/(2*a)), (sqrt(abs(delta)))/(2 * a));
    		}
    		printf("%d\n", 2 * a);
    	}
    	if (delta == 0)
    	{
    		printf("Une solution reelle double :\n\n");
    		int d = printf("%d\n",-b);
    		int e;
    		for (e = 1; e <= d; e++)
    		{
    			printf("-");
    		}
    		printf(" = %f\n", (float)-b/(2*a));
    		printf("%d\n", 2 * a);
    	}
    	return EXIT_SUCCESS;
    }
     
    static int
    racine_delta(int delta)			// Fonction retournant la racine du plus grand carré entier dont delta est un multiple
    {
    	if (delta < 0)
    	{
    		delta = abs(delta);
    	}
     
     
    		int val_maxi = floor(sqrt(delta));
    		int i;
    		int t = 1;
    		for (i = val_maxi; i > 0; i--)
    		{
    			if ( delta - (floor(delta/(i*i))*(i*i)) == 0)
    			{
    				t = i;
    				i = -1;
    			}
    		}
    	return t;
    }
     
    static void
    usage(char *s)
    {
    	fprintf(stderr, "Usage: %s \"a\" \"b\" \"c\" avec a different de zero", s);
    	exit(EXIT_FAILURE);
    }
    Voila, quelques petites questions :
    Pourquoi suis-je obligé de mettre (float)-b/(2 * a) pour obtenir un float avec une divisions de deux entiers ??? (Sinon, il me considere le resultat comme un entier et ne fait qu'un arrondi entier au lieu d'un décimal

    Autre soucis, pour le int a = floor(atof(argv[1])); j'ai testé la fonction atoi a tout hasard lol, il y a un bug. Qqn saurait il comment passer un argument du programme en int sans ce lourd procédé.

    Enfin, dites moi ce que vous pensez de ce prog. Et ne dites pas seulement qu'il est nul plz, dite aussi pourquoi. Si vous trouvez que qqch peut etre amélioré, dites le, ca m'aidera toujours.

    Pour le moment, le prog ne fonctionne bien qu'avec des entiers, pour les décimaux, le floor le transforme en entiers.

    Voila, merci à vous de votre attention en tout cas.

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Pourquoi suis-je obligé de mettre (float)-b/(2 * a) pour obtenir un float avec une divisions de deux entiers ??? (Sinon, il me considere le resultat comme un entier et ne fait qu'un arrondi entier au lieu d'un décimal
    Parce que tes variables sont des entiers donc ce sont des opérations entières qui sont faites. Le fait que cela soit mis dans un flottant n'est considéré qu'après le calcul. La meilleure solution serait de faire tout en double depuis le début.

    Autre soucis, pour le int a = floor(atof(argv[1])); j'ai testé la fonction atoi a tout hasard lol, il y a un bug. Qqn saurait il comment passer un argument du programme en int sans ce lourd procédé.
    atoi n'est plus à utilisé de toute façon, on utilise strtol. Mais tu vas devoir utiliser strtod parce que tes calculs doivent être en double (ou flottants bien sûr).

    Enfin, dites moi ce que vous pensez de ce prog. Et ne dites pas seulement qu'il est nul plz, dite aussi pourquoi. Si vous trouvez que qqch peut etre amélioré, dites le, ca m'aidera toujours.
    Je dirais :

    Pour le moment, le prog ne fonctionne bien qu'avec des entiers, pour les décimaux, le floor le transforme en entiers.
    Pourquoi avoir laissé un tel programme avec des entiers ? Pourquoi avoir commencé avec des entiers ? Cela n'a pas de sens pour le problème actuel.

    Sur le code, en compilant j'ai ceci :
    sec.c: In function 'main':
    sec.c:17: warning: empty body in an if-statement
    qui fait référence à ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	if (a == 0);
    		usage(argv[0]);
    Erreur de copier coller ?? Parce que sinon le code ne fonctionne pas du tout...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #include <float.h>
    Je ne connaissais pas ce fichier d'en-tête et il est inutile ici...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static int racine_delta(int delta);
    Comment la racine de delta peut être un entier ?? T'imagines le peu de cas que tu es en train de résoudre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    	if (argc != 4)
    		usage(argv[0]);
    	int a = floor(atof(argv[1]));
    	if (a == 0);
    		usage(argv[0]);
    	int b = floor(atof(argv[2]));
    	int c = floor(atoi(argv[3]));
     
    	int delta = (b * b) - (4 * a * c);
    Non, on utiliserait plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    		if (argc != 4)
    		usage(argv[0]);
    	double a = strtod(argv[1],NULL);
     
    	if (abs(a) < 0.0001)
    		usage(argv[0]);
     
    	double b = strtod(argv[2],NULL);
    	double c = strtod(argv[3],NULL);
     
    	double delta = (b * b) - (4 * a * c);
    Forcément cela devient donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(abs(delta)>0.0001)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    		printf("Deux solutions %s :\n\n", (delta < 0) ? "complexes et conjuguees" : "reelles");
    		int d = printf("%d + %s(%d * rac(%d))\n", -b, (delta < 0) ? "i" : "", racine_delta(delta), abs(delta / (racine_delta(delta) * racine_delta(delta))));
    		int e;
    		for (e = 1; e <= d; e++)
    		{
    			printf("-");
    		}
    		if (delta > 0)
    		{
    			printf(" = %f\n", (-b + sqrt(delta)) / (2 * a));
    		}
    		else if (delta < 0)
    		{
    			printf(" = %f + i * %f\n", ((float)-b/(2*a)), (sqrt(abs(delta)))/(2 * a));
    		}
    		printf("%d\n\n", 2 * a);
     
    		d = printf("%d - %s(%d * rac(%d))\n", -b, (delta < 0) ? "i" : "", racine_delta(delta), abs(delta / (racine_delta(delta) * racine_delta(delta))));
    		for (e = 1; e <= d; e++)
    		{
    			printf("-");
    		}
    		if (delta > 0)
    		{
    			printf(" = %f\n", (-b + sqrt(delta)) / (2 * a));
    		}
    		else if (delta < 0)
    		{
    			printf(" = %f - i * %f\n", ((float)-b/(2*a)), (sqrt(abs(delta)))/(2 * a));
    		}
    		printf("%d\n", 2 * a);
    	}
    Désolé mais c'est trop tôt pour faire des maths, faudra changer quelques détails pour faire fonctionner ce code avec des doubles...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	if (delta == 0)
    	{
    		printf("Une solution reelle double :\n\n");
    		int d = printf("%d\n",-b);
    		int e;
    		for (e = 1; e <= d; e++)
    		{
    			printf("-");
    		}
    		printf(" = %f\n", (float)-b/(2*a));
    		printf("%d\n", 2 * a);
    	}
    Devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	if(abs(delta)<0.0001)
    	{
    		printf("Une solution reelle double :\n\n");
    		int d = printf("%f\n",-b);
    		int e;
    		for (e = 1; e <= d; e++)
    		{
    			printf("-");
    		}
    		printf(" = %f\n", -b/(2*a));
    		printf("%f\n", 2 * a);
    	}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    static int
    racine_delta(int delta)			// Fonction retournant la racine du plus grand carré entier dont delta est un multiple
    {
    	if (delta < 0)
    	{
    		delta = abs(delta);
    	}
     
     
    		int val_maxi = floor(sqrt(delta));
    		int i;
    		int t = 1;
    		for (i = val_maxi; i > 0; i--)
    		{
    			if ( delta - (floor(delta/(i*i))*(i*i)) == 0)
    			{
    				t = i;
    				i = -1;
    			}
    		}
    	return t;
    }
    Trop compliqué... En double, c'était nettement plus facile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static double
    racine_delta(double delta)			// Fonction retournant la racine du plus grand carré entier dont delta est un multiple
    {
    	if (delta < 0)
    	{
    		delta = abs(delta);
    	}
     
    	return sqrt(delta);
    }
    En gros, le code avait l'air de fonctionner (sauf le warning de base) mais résoudre des équations avec des entiers lorsque le faire avec des doubles simplifie tellement les choses...

    Jc

  3. #3
    Membre actif Avatar de Gamdwin
    Inscrit en
    Avril 2005
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 186
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par fearyourself
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #include <float.h>
    Je ne connaissais pas ce fichier d'en-tête et il est inutile ici...
    En fait, float.h est pratique parce qu'il contient des constantes telles que DBL_MAX ou DBL_EPSILON, bref les constantes usuelles de manipulation de données de type float/double.
    C'est standard depuis C89.

    Un site que j'aime bien utiliser :
    http://www.schweikhardt.net/identifiers.html

    (mais je suis d'accord : son inclusion ne sert à rien ici)
    "I hate quotations. Tell me what you know." (Ralph Waldo Emerson)

  4. #4
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par fearyourself
    Forcément cela devient donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(abs(delta)>0.0001)
    Pourquoi 0.0001, t'as trouvé cette valeur dans le fond de ton café ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (abs (delta - 0) > FLT_EPSILON)

  5. #5
    Membre actif Avatar de Gamdwin
    Inscrit en
    Avril 2005
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 186
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par gege2061
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (abs (delta - 0) > DBL_EPSILON)
    (vu que delta est un double)
    "I hate quotations. Tell me what you know." (Ralph Waldo Emerson)

  6. #6
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par gege2061
    Pourquoi 0.0001, t'as trouvé cette valeur dans le fond de ton café ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (abs (delta - 0) > FLT_EPSILON)

    Déjà de 1 : je bois pas de café

    Deuxièmement :
    Citation Envoyé par Gamdwin
    if (abs (delta - 0) > DBL_EPSILON)


    Et enfin, je sais pas pourquoi...

    Jc

  7. #7
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par fearyourself
    Déjà de 1 : je bois pas de café
    Tu as pensé à t'y mettre, ça te ferait le plus grand bien

    Citation Envoyé par fearyourself
    Deuxièmement :

    Citation Envoyé par Gamdwin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (abs (delta - 0) > DBL_EPSILON)
    Pas trop dur sur ce coup là

    J'me suis planté dans mon copier/coller, merci Gamdwin

  8. #8
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Ok ! Je vous remercie à tous pour vos réponses. Je vais donc reconsidérer le programme.

    La fonction racine_delta renvoie un entier. Elle permet par exemple pour racine(18) de renvoyer l'entier 3. Ainsi racine(18) est remplacé par 3 * racine(2).

    Pour le if (a==0); Il ne figure pas dans mon prog, ca doit etre effectivement une erreur de copier/coller.

    Merci à tous pour vos contributions en tout cas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Visual basic: algo résolvant une équation du second degré
    Par mauriiice dans le forum VB 6 et antérieur
    Réponses: 15
    Dernier message: 05/12/2005, 17h16
  2. [LG] Recherche de petits programmes Pascal
    Par Sid ali dans le forum Langage
    Réponses: 1
    Dernier message: 24/11/2005, 14h03
  3. aide petit programme pour débutant
    Par kartp0rqx dans le forum C
    Réponses: 16
    Dernier message: 14/10/2005, 19h31
  4. Faisabilité d'un petit programme FTP...
    Par ptit_seb dans le forum Windows
    Réponses: 2
    Dernier message: 15/09/2005, 21h10
  5. [SRC] Petit programme avec BD
    Par Nico62 dans le forum C++Builder
    Réponses: 3
    Dernier message: 10/01/2005, 20h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo