Partage
  • Partager sur Facebook
  • Partager sur Twitter

la division par zero

Sujet résolu
    30 septembre 2008 à 20:34:31

    y a t il un moyen d'éviter le plantage d'un programme en C quand on fait une division par zero? :-°
    merci pour vos reponses.
    • Partager sur Facebook
    • Partager sur Twitter
      30 septembre 2008 à 20:37:25

      vérifier si tu ne divise pas par 0....
      tu n'aurais pas un bout de code à nous montrer?
      • Partager sur Facebook
      • Partager sur Twitter
        30 septembre 2008 à 20:40:28

        Salut,

        J'ai jamais testé, mais je crois bien que tu peux utiliser les signaux.

        A+
        • Partager sur Facebook
        • Partager sur Twitter
          30 septembre 2008 à 20:48:43

          merci pour le site, va faloir que j'achète un dico d'anglais pour traduire :-°
          En fait pour être plu clair :
          de mémoire jadis quand je programmais avec mon ZX-Spectrum, je pouvais tester un registre de type "Flags" et il y avait un byte de ce flag dont :
          état 0 : operation correcte
          etat 1 : operation non correcte OVERFLOW
          je voudrais faire la même chose .
          merci de vos reponses.
          • Partager sur Facebook
          • Partager sur Twitter
            30 septembre 2008 à 20:56:54

            Bah là, en fait le principe est d'intercepter un signal (exceptions, fermeture de programme, ...) et de spécifier l'action à faire lors de cette interception (récupération dans une fonctions, ignorer, récupération par défaut).

            Donc si j'ai bien compris, il faut inclure <signal.h> et utiliser la fonction signal avec comme flag SIGFPE.

            Je te laisse trouver ce que ça va donner ^^ .

            A+
            • Partager sur Facebook
            • Partager sur Twitter
              30 septembre 2008 à 22:11:24

              Et pourquoi ne pas tout simplement vérifier si le diviseur n'est pas 0 comme l'a dit max ?
              • Partager sur Facebook
              • Partager sur Twitter
                30 septembre 2008 à 22:19:59

                Bien sûr on peut faire ça mais ça ne répond pas à la question de départ.
                • Partager sur Facebook
                • Partager sur Twitter
                  30 septembre 2008 à 22:25:30

                  Pourqoi faire simple quand on peut faire compliquer n'est-ce pas ?
                  Si le P.O. a une bonne raison pour ne pas vouloir vérifier le diviseur il faut qu'il la donne car on n'avance pas beaucoup.
                  La vérification des registres doit pouvoir se faire avec quelques lignes d'assembleur, mais une gestion d'interruption est surement plus simple.
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

                    1 octobre 2008 à 6:09:19

                    le pourquoi de ma question :
                    probleme a resoudre :
                    soit la fonction
                    f(x)= 1/ (x-a) ou a € ]-infini, infini[ etudier et tracer la fonction.
                    a part le fait d'exclure tous les cas ]-infini, infini[ cela revient a ne rien faire !
                    Par contre si je peux recuperer l'erreur de calcul pour faire autre chose, je gère moi même l'erreur ! :-°
                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 octobre 2008 à 10:40:32

                      Citation : zx-spectrum

                      y a t il un moyen d'éviter le plantage d'un programme en C quand on fait une division par zero? :-°
                      merci pour vos reponses.


                      SIGFPE
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Music only !
                        1 octobre 2008 à 12:55:27

                        Une bibliothèque de gestion d'exception fait par dnob700 du forum programmation de jv.com, à voir ce que ça vaut.

                        http://repository.sectionpc.info/C/cexn.tar.gz
                        • Partager sur Facebook
                        • Partager sur Twitter
                          1 octobre 2008 à 21:43:34

                          bonsoir,
                          merci Noob4ever pour le lien , j'étudierais a tête reposé.

                          Citation : ed

                          SIGFPE



                          désolé Ed j'ai pas compris , je suis un néophyte pas un pro !Peut tu m'éclairer merci
                          • Partager sur Facebook
                          • Partager sur Twitter
                            1 octobre 2008 à 22:11:19

                            Citation : zx-spectrum

                            Citation : ed

                            SIGFPE



                            désolé Ed j'ai pas compris , je suis un néophyte pas un pro !Peut tu m'éclairer merci


                            Si tu lisais ce que je dis, tu aurais peut-être compris...
                            • Partager sur Facebook
                            • Partager sur Twitter
                              17 octobre 2008 à 21:46:45

                              Bon je viens de consulter la documentation en anglais sur les signaux, je n'est pas encore les compétences requises ! si quelqu'un a déjà une solution prête à l'emploie ,
                              merci d'avance
                              • Partager sur Facebook
                              • Partager sur Twitter
                                20 octobre 2008 à 19:29:34

                                bonjour,
                                suite de mon probleme de division par zero !
                                j'ai trouve un bout de code que voici :
                                #include <stdio.h>
                                #include <stdlib.h>
                                #include <signal.h>
                                
                                char tmpfilename [L_tmpnam];
                                
                                void terminate (int param)
                                {
                                  printf ("Terminating program...\n");
                                  remove (tmpfilename);
                                  exit(1);
                                }
                                
                                int main ()
                                {
                                  void (*prev_fn)(int);
                                  double a;
                                
                                  prev_fn = signal (SIGTERM,terminate);
                                  if (prev_fn==SIG_IGN) signal (SIGTERM,SIG_IGN);
                                
                                  tmpnam (tmpfilename);
                                
                                  /* code here */
                                  a= 1/0,00001;
                                  printf("%lf",a);
                                
                                  return 0;
                                }
                                


                                qui peut me l'expliquer ?
                                j'ai rajouté les lignes 25 & 26. Evidemment le programme se plante !
                                -----> mon but est de pouvoir traiter l'erreur pour eviter le plantage pur et dur.
                                Merci de votre aide.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  20 octobre 2008 à 19:44:35

                                  Hum, c'est 0.000001 pas 0,000001 !
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    20 octobre 2008 à 21:12:59

                                    T'as vraiment rien compris...

                                    Bon déjà, voila un code qui marche :
                                    #include <stdio.h>
                                    #include <stdlib.h>
                                    #include <signal.h>
                                    
                                    void fpe (int param)
                                    {
                                            printf ("Division par zero\n");
                                            exit (1); // Quitte le programme, car sinon la division par zéro serait répéter indéfiniment
                                    }
                                    
                                    int main ()
                                    {
                                            double a;
                                    
                                            signal (SIGFPE, fpe); // Redirige le signal SIGFPE
                                    
                                            a = 1/0; // Division par zéro
                                    
                                            return 0;
                                    }
                                    

                                    La fonction fpe est la fonction qui sera appelée lors des problèmes d'arithmétiques de ton programme (division par zéro notamment). Elle doit suivre le modèle void fn (int).
                                    Ensuite, la fonction main, avant de faire une division par zéro appelle la fonction signal (de signal.h) qui attend 2 paramètres : le signal à intercepter (un int), et un pointeur de fonction suivant le modèle void fn (int). Ici, le signal à intercepter est SIGFPE, c'est à dire les erreurs d'arithmétiques, et ce signal est redirigé vers la fonction "fpe". Lors de la division par zéro, la fonction fpe est appelée, et celle-ci quitte le programme afin d'éviter une boucle infinie du signal (enlève le exit pour voir ce que ça fait si tu n'as pas compris).

                                    Encore une fois, lis ça.

                                    J'espère t'avoir aidé.

                                    A+
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      21 octobre 2008 à 20:39:58

                                      Merci Royalbru pour ton explication. J'y vois légèrement plus clair :p
                                      voici mon code :
                                      #include <stdio.h>
                                      #include <stdlib.h>
                                      #include <signal.h>
                                      
                                      void fpe (int param)
                                      {
                                              printf ("Division par zero\n");
                                              exit (1); // Quitte le programme, car sinon la division par zéro serait répéter indéfiniment
                                      }
                                      
                                      int main ()
                                      {
                                              double a;
                                              long b;
                                      
                                              signal (SIGFPE, fpe); // Redirige le signal SIGFPE
                                              for (b=-10;b<10;b++)
                                              {
                                                  a = 1/b; // Division par zéro
                                                  printf("%ld / %ld = %lf \n",1,b,a);
                                              }
                                      
                                      
                                              return 0;
                                      }
                                      





                                      Bon cela résoud la moitié de mon problème, car quand j'arrive à b=0, je divise par zero, et j'affiche donc "division par zero" et le programme s'arrête sans se planter. Sauf que le programme m'a fait la moitié du boulot car il ne m'excecutes pas le reste de la boucle de 1 a 9.
                                      Pour resumer voici ce que je voudrais faire , je le traduit avec un algorithme:

                                      n <--0
                                      Pour B variant de [valeur1 à valeur2]
                                      calcul de 1/b
                                      si
                                      debut
                                      1/b est realisable alors resultat = 1/b
                                      fin si
                                      sinon
                                      debut
                                      valeurAretirer[n]=b
                                      n <--- n+1
                                      fin sinon
                                      fin boucle pour


                                      Au fait tant que j'y suis existe t il un moyen de traduire des pages web Anglais -----> Francais , j'avoue avoir du mal a traduire , mon anglais date de plus de 20 ans !
                                      merci
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        22 octobre 2008 à 21:30:52

                                        Bah dans ce cas là, il y a beaucoup plus simple :
                                        #include <stdio.h>
                                        #include <stdlib.h>
                                        
                                        int main ()
                                        {
                                                double a;
                                                long b;
                                        
                                                for (b=-10;b<10;b++)
                                                {
                                                        if (b != 0)
                                                        {
                                                                a = 1.0/b;
                                                                printf("%d / %ld = %lf \n",1,b,a);
                                                        }
                                                        else
                                                        {
                                                                printf ("Erreur : Division par zéro !\n");
                                                        }
                                                }
                                        
                                                return 0;
                                        }
                                        

                                        Ou encore plus simple si tu utilises des nombres à virgules flottantes :
                                        #include <stdio.h>
                                        #include <stdlib.h>
                                        
                                        int main ()
                                        {
                                                double a;
                                                long b;
                                        
                                                for (b=-10;b<10;b++)
                                                {
                                                        a = 1.0/b;
                                                        printf("%d / %ld = %lf \n",1,b,a);
                                                }
                                        
                                                return 0;
                                        }
                                        

                                        Car, les interruptions de divisions par zéro sont déclenchées pour les entiers seulement (presque certain). Donc, ici, tu auras le résultat de ta division à savoir <math>\(\infty\)</math> (si le dividende est différent de 0 seulement).

                                        A+
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          23 octobre 2008 à 19:33:46

                                          ok, merci Royalbru.
                                          Je suis surpris par le resultat de la division de 1/0 quand on travaille avec le type long et double :-°
                                          Je pensais que c'était impossible, or a priori il existe un nombre infini qui est predefinie :-°
                                          Bon je vais pouvoir poursuivre et pouvoir etudier et tracer des fonction du type :
                                          1/ln(x*x-x+1) ou là à priori ln(x*x-x+1)=0 n'est pas forcement facile a trouver !
                                          Merci pour ta patience.
                                          @+
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            23 octobre 2008 à 19:52:39

                                            Le type double réserve certaines variables pour les infinis et les erreurs (en cas de doute, penser a vérifier la valeur de errno).
                                            Plus d'informations ici.

                                            Il faut prendre garde a bien cerner le fonctionnement des réels (float, double) avant de travailler avec. L'option de compilation GCC -Wfloat-equal, par exemple, n'existe pas pour rien.

                                            Consulter la doc de <float.h>...
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              23 octobre 2008 à 21:10:04

                                              Ok merci Yoch pour ce complement :)
                                              Il est vrai que je vais me pencher d'un peu plus pres sur la question !
                                              @+
                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              la division par zero

                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                              • Editeur
                                              • Markdown