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 :

Probleme : equation du second degré


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    etudiant
    Inscrit en
    Novembre 2015
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : etudiant
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2015
    Messages : 13
    Points : 12
    Points
    12
    Par défaut Probleme : equation du second degré
    Bonjour

    Actuellement je souhaite créer un programme qui calcule les équations du second degré mais je rencontre quelques problèmes sur mes résultats et je ne comprends pas pourquoi.
    Voici mon code :

    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
     
     
    /* Pour afficher un charactère */
    void....display(char c)                                                       
    {                                                                                
      write(1, &c, 1);                                                               
    }                                                                                
     
    /* Pour afficher un nombre */                                                                             
    int.....put_nbr(int nb)                                                       
    {                                                                                
      if (nb == -2147483647)                                                         
      {                                                                              
        write(1, "-2147483647", 11);                                                 
        return (0);                                                                  
      }                                                                              
      if (nb < 0)                                                                    
      {                                                                              
        display('-');                                                             
        nb *= -1;                                                                    
      }                                                                              
      if (nb > 9)                                                                    
      {                                                                              
        put_nbr(nb / 10);                                                         
        put_nbr(nb % 10);                                                         
      }                                                                              
      else                                                                           
        display(nb + '0');                                                         
      return (0);                                                                    
    }                                                                                
     
    /* Calcule la racine carré */ 
    int.....square_root(int nb)                                                          
    {                                                                                
      int...r;                                                                       
      int...i;                                                                       
     
      i = 1;                                                                         
      r = 1;                                                                         
      if (nb == 1)                                                                   
        return (1);                                                                  
      while (i < nb && i <= 46340 && nb < 2147483647)                                
      {                                                                              
        r = nb - (i * i);                                                            
        if (r == 0)                                                                  
          return (i);                                                                
        else if (r < 0)                                                              
          return (0);                                                                
        i++;                                                                         
      }                                                                              
      return (r);                                                                    
    }                                                                                
     
    void....equation(int *a, int *b, int *c)                            
    {                                                                                
      int...D;                                                                       
      int...D2;                                                                      
      int...r1;                                                                      
      int...r2;                                                                      
     
      D = (*b * (*b)) - (4 * (*a) * (*c));                                           
      D2 = D;                                                                        
      if (D == 0)                                                                    
      {                                                                              
        r1 = ((-*b) / (2 * (*a)));                                                   
        put_nbr(r1);                                                              
        display('\n');                                                            
      }                                                                              
      if (D > 0)                                                                     
      {                                                                              
        r1 = (-*b - sqrt(D)) / (2 * *a);                                          
        r2 = (-*b + sqrt(D2)) / (2 * *a);
        put_nbr(r1);                                                  
        display('\n');                                                            
        put_nbr(r2);                                                                                                                       
      }                                                                              
      if (D < 0)                                                                     
        display('0');                                                             
    }
    Quand je rentre comme argument "1" "12" "1" (a = 1, b = 12, c = 1)
    J'ai un discriminant de 140 > 0 donc normalement deux solutions qui sont censées être -11,9 (racine 1) et -0,08 (racine 2) environ. (vu que mes fonctions sont en int, les résultats devraient être arrondis si je ne dis pas de bêtises).
    Mais mon programme me renvoie -6 pour chaque solution.
    Une idée ?

    Merci.

  2. #2
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    ma première idée c'est qu'à vouloir compliquer les choses exagérément, on obtient des résultats inattendus, donc mon conseil:
    - utilise printf plutôt que de faire ta propre fonction d'affichage
    - utilise sqrt plutôt que ta propre fonction de racine carrée (il y a de quoi faire bcp mieux, cela dit en passant)
    - utilise des valeurs plutôt que des pointeurs lorsque ce n'est pas nécessaire
    - utilise des float plutôt que des int ( au passage: (int) 1.6 == 1, pas à 2: la valeur n'est pas arrondie mais tronquée
    - évite les petits points entre un type et la variable lors de la déclaration
    - commente ton code

    et je suis persuadé que la solution te sautera aux yeux...

  3. #3
    Membre à l'essai
    Homme Profil pro
    etudiant
    Inscrit en
    Novembre 2015
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : etudiant
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2015
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    Salut
    - utilise printf plutôt que de faire ta propre fonction d'affichage
    - utilise sqrt plutôt que ta propre fonction de racine carrée (il y a de quoi faire bcp mieux, cela dit en passant)
    C'est vrai mais je souhaite vraiment utiliser les fonctions que j'ai crée quitte a les améliorer si il le faut.

    - utilise des valeurs plutôt que des pointeurs lorsque ce n'est pas nécessaire
    Il faut que j'utilise les arguments lors de l'execution du a.out, les pointeurs sont obligatoire pour cela, non?

    - utilise des float plutôt que des int ( au passage: (int) 1.6 == 1, pas à 2: la valeur n'est pas arrondie mais tronquée
    Pour le moment je n'utilise que des int et la valeur tronquée (merci, je pensais qu'elle était arrondie) ne me pose pas de probleme. Je recherche juste a avoir un resultat approximatif sinon il est claire que j'aurai utilisé des float.

    - évite les petits points entre un type et la variable lors de la déclaration
    - commente ton code
    Les petits points se font via mon vimrc, ca ne change rien au code, c'est juste pour montrer que c'est une tabulation et non des espaces.
    Je vais editer mon premier poste et ajouter les commentaires.

    Merci

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par CrH4A4cK Voir le message
    C'est vrai mais je souhaite vraiment utiliser les fonctions que j'ai crée quitte a les améliorer si il le faut.
    Comme c'est Épitesque. Mes remarques:
    • Les valeurs magiques, caymal. Utilise STDOUT_FILENO à la place de 1. De même, utilise '0' à la place de 48.
    • Pourquoi -2147483647 comme cas particulier? Le seul nombre signé 32-bits qui ne peut pas être exprimé positivement, c'est -2147483647 - 1.
      • D'ailleurs, ma remarque au-dessus s'applique: Utilise INT_MIN à la place (plus une paire de macros avec l'opérateur # pour en faire une chaîne).
    • Pour ta fonction de racine carrée kustom, du devrais éviter d'utiliser le vrai nom de la fonction. Utilise un nom perso, quitte à rediriger ensuite dessus avec un #define.



    Citation Envoyé par CrH4A4cK Voir le message
    Il faut que j'utilise les arguments lors de l'execution du a.out, les pointeurs sont obligatoire pour cela, non?
    Tes arguments une fois parsés sont des valeurs; il est inutile de passer des pointeurs vers celles-ci (qui plus est, des pointeurs non-const) à une fonction qui ne les modifie pas.

    Les petits points se font via mon vimrc, ca ne change rien au code, c'est juste pour montrer que c'est une tabulation et non des espaces.
    Le problème, c'est que tous les éditeurs de texte que je connais utilisent des points pour leurs espaces et (souvent) des flèches pour les tabulations, et sûrement pas l'inverse.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre à l'essai
    Homme Profil pro
    etudiant
    Inscrit en
    Novembre 2015
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : etudiant
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2015
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    Salut
    Les valeurs magiques, caymal. Utilise STDOUT_FILENO à la place de 1. De même, utilise '0' à la place de 48.
    Ok c'est noté. Par contre je ne connait pas du tout le : STDOUT_FILENO
    Qu'est ce que c'est exactement? ( je ferai des recherches demain)

    Pourquoi -2147483647 comme cas particulier? Le seul nombre signé 32-bits qui ne peut pas être exprimé positivement, c'est -2147483647 - 1.
    J'avais a faire ca dans un exercice, du coup j'ai prit l'habitude d'écrire ma fonction d'affichage pour les nombres comme ça, mais si ca gène je peux le virer.

    D'ailleurs, ma remarque au-dessus s'applique: Utilise INT_MIN à la place (plus une paire de macros avec l'opérateur # pour en faire une chaîne).
    Pour ta fonction de racine carrée kustom, du devrais éviter d'utiliser le vrai nom de la fonction. Utilise un nom perso, quitte à rediriger ensuite dessus avec un #define.
    INT_MIN est une macro déjà existente?
    Pour la fonction "racine carré kustom", j'ai utilisé un autre nom que sqrt, c'était juste pour vous aider a la comprehension de ma fonction (vue que je n'ai pas mit de commentaire pour le moment).

    Le problème, c'est que tous les éditeurs de texte que je connais utilisent des points pour leurs espaces et (souvent) des flèches pour les tabulations, et sûrement pas l'inverse.
    C'est pas très grave non? c'est juste pour moi, pour eviter de me tromper.
    Sinon si ca vous gène vraiment je vire ces points

    Merci pour les remarques!

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par CrH4A4cK Voir le message
    Ok c'est noté. Par contre je ne connait pas du tout le : STDOUT_FILENO
    Qu'est ce que c'est exactement? ( je ferai des recherches demain)
    Comme son nom l'indique: Standard Output File Number.
    Quelque part dans <unistd.h>, il y a un code comme ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define STDIN_FILENO 0
    #define STDOUT_FILENO 1
    #define STDERR_FILENO 2


    J'avais a faire ca dans un exercice, du coup j'ai prit l'habitude d'écrire ma fonction d'affichage pour les nombres comme ça, mais si ca gène je peux le virer.
    Je ne te reproche pas de faire un cas particulier pour la valeur qui ne peut pas être positive. Je te reproche de t'être trompé de valeur.


    INT_MIN est une macro déjà existente?
    Oui, définie dans <limit.h>.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par CrH4A4cK Voir le message
    C'est vrai mais je souhaite vraiment utiliser les fonctions que j'ai crée quitte a les améliorer si il le faut.
    Bonjour

    Voici un algo pour la racine carrée. Il s'appuie sur la limite de la suite U0=X (n'importe quoi mais différent de 0) et Un+1=1/2(Un + P/Un) qui tend vers racine(P) quand n tend vers infini
    Code c : 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
    double racine(
    	float nb)					//Paramètre recevant le nombre dont on veut la racine
    {
    	// Déclaration des variables
    	double calc;					// Calcul de la racine dans la boucle
    	double diff;					// Pour tester la différence avec la valeur précédente
     
    	// Si la racine n'a pas besoin d'être calculée (pour "0" ou "1")
    	if (nb == 0.0 || nb == 1.0)
    		return (nb);				// Ici, racine de "nb" vaut "nb"
     
    	// Initialisation début de boucle
    	calc=nb;					// Ou n'importe quel nombre différent de "0"
     
    	do {
    		// Récupération de "calc" pour comparer avec le calcul suivant
    		diff=calc;
     
    		// Approximation de la racine (le calcul se fera en précision "double")
    		calc=0.5 * (calc + nb / calc);
     
    	// Tant que le processeur peut faire la différence entre ce calcul et le précédent (limite) 
    	} while (calc != diff);
     
    	// Renvoi du résultat calculé
    	return calc;					// Ou bien "return diff" puisque ici, "diff" = "calc"
    }

    Et le "calc != diff" est une astuce qui se sert de la limite mathématique de ton processeur. Quand le nombre devient si fractionnaire que ton processeur n'arrive plus à faire la différence entre ce nombre et celui calculé juste avant, alors tu peux arrêter de calculer. Ca évite d'utiliser des valeurs arbitraires pour arrêter le calcul.

    Sinon tu as un autre algorithme assez sympa aussi: choisir 2 variables "X" et "Y" avec "X" différent de "0" et boucler sur les opérations suivantes
    • Y = N / X
    • X = (X + Y) / 2

    A chaque boucle les variables "X" et "Y" vont se rapprocher de la racine de "N" par encadrement
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    En tout cas, si tu veux utiliser tes propres fonctions pour chaque chose, il faut que tu les testes de façon approfondie.

    Le problème dans ta question, c'est qu'à défaut d'une erreur qui saute aux yeux dans le calcul des racines de l'équation, on ne sait pas trop où chercher: est-ce une défaillance de l'affichage, du calcul des racines carrées, un problème d'arrondi? Imagine maintenant que tu écrives un programme -qui restera modeste au demeurant- contenant une trentaine de fonctions et un ou deux milliers de lignes de code.

    Je crois également que, si tu veux utiliser tes propres fonctions, il faut que tu y mettes plus de coeur et ne te contentes pas d'approximations et de work-arounds comme l'utilisation d'entiers ou de constantes magiques (ex -2147483647). Comment pourras-tu les tester si tu ne sais pas quelle valeur attendre de leur retour? Parce que savoir quelle sera la racine carrée de 140 quand elle est calculée avec des entiers, et a fortiori les solutions d'une équation de second degré, est un travail fatigant.

    "1972 - Dennis Ritchie invents a powerful gun that shoots both forward and backward simultaneously. Not satisfied with the number of deaths and permanent maimings from that invention he invents C and Unix." (toute l'histoire ici). Donc à manipuler avec précaution, pas en fermant les yeux après une bonne cuite...

  9. #9
    Membre à l'essai
    Homme Profil pro
    etudiant
    Inscrit en
    Novembre 2015
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : etudiant
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2015
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    Salut

    Quelque part dans <unistd.h>
    Merci j'ai lu le man.
    Je te reproche de t'être trompé de valeur
    Oui, c'est corrigé sur mon programme.
    il faut que tu les testes de façon approfondie.
    Merci pour l'algorithme, je vais tester ca!

    En tout cas j'ai comprit d'où viennent mes "grosses" erreures :
    La première c'est la fonction qui calcul la racine carré.
    Du coup la deuxième erreure va venir de ma fonction qui affiche les nombres.

    Je vais corriger tout ça. Je reviendrai vers vous si je rencontre encore des soucis sur ce programme mais j'en doute.

    Merci a tous!

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

Discussions similaires

  1. equation du second degre
    Par Manudeparis dans le forum C
    Réponses: 5
    Dernier message: 06/11/2011, 14h42
  2. [Turbo Pascal] [Débutant] Equation du second degré
    Par MEGA-STORM dans le forum Turbo Pascal
    Réponses: 2
    Dernier message: 28/11/2008, 17h25
  3. [Turbo Pascal] Equation du second degré
    Par Zero_System dans le forum Turbo Pascal
    Réponses: 2
    Dernier message: 13/10/2008, 22h16
  4. Réponses: 6
    Dernier message: 17/11/2007, 13h17
  5. [TP] Equation du second degré
    Par WhiteTigerZ dans le forum Turbo Pascal
    Réponses: 8
    Dernier message: 08/11/2006, 22h00

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