Partage
  • Partager sur Facebook
  • Partager sur Twitter

Affichage d'un nombre flottant

    26 juin 2022 à 16:02:16

    Salut tout le monde!

    Déjà rassurez vous, je ne viens pas vous demander comment afficher un nombre flottant en C.

    Mon problème est le suivant: disons que je veuille afficher exactement 7 chiffres d'un nombre flottant, parties entières et décimales inclues. Je ne peux pas faire 

    printf("%.6lf", number);

    puisque ça fonctionnera uniquement pour les nombres inférieur à 10.

    Du coup j'aimerais savoir s'il ya une technique potable pour le faire. Une qui fonctionnerait pour les nombres inférieur à 10, 100, 1000, 10000...etc. La solution qui m'est venue à l'esprit pour le moment est d'utiliser la fonction modf() de math.h de la manière suivante:

    void split_fxn(double number)
    {
        double integral_part = 0, fractional_part = 0;
    
        fractional_part = modf(number, &(integral_part));
    
        if(integral_part < 10)
            printf("%.6f\t", number);
        else if(integral_part < 100)
            printf("%.5f\t", number);
        else if(integral_part < 1000)
            printf("%.4f\t", number);
        else if(integral_part < 10000)
            printf("%.3f\t", number);
    
    }


    Je crois qu'on est tous d'accord sur le fait que ma fonction split_fxn() est non seulement bancales, mais en plus ne résout que partiellement le problème. Alors s'il ya une meilleure technique, prière de bien vouloir la partager avec moi.

    Bien cordialement,

    Christian

    • Partager sur Facebook
    • Partager sur Twitter
      26 juin 2022 à 17:22:55

      Le format peut être encodé dans une chaîne comme suit:

      On peut faire log10(a)+1;  pour obtenir le nombre de digits avant le point.
       
      #include <stdio.h>
      int main(void) {
          char fmt[10] = "%7.5lf";
          int n=2;   // nombre de digits avant le point.
          sprintf(fmt, "%%%d.5lf", n+6);
          printf("%s\n", fmt);
          double a = 12.34567;
          printf(fmt, a);printf("\n");
      }
       
      %8.5lf                                                                                                                  
      12.34567

      -
      Edité par PierrotLeFou 26 juin 2022 à 17:35:29

      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        26 juin 2022 à 17:39:43

        Tu peux faire plus simple pour ta fonction et sans fonction de math

        #include <stdio.h>
        
        void split_fxn(double number, int nbdigit)
        {
            int integral_part = 0;
            int tmp=number;
            while(tmp>9)
            {
                tmp=tmp/10;
                integral_part++;
            }
            printf("%.*f\n", nbdigit-integral_part-1, number);
        }
        
        int main(void)
        {
            split_fxn(9.9999, 7);
            split_fxn(10.0, 7);
            split_fxn(0.123, 7);
            split_fxn(1.123, 7);
            split_fxn(12.123, 7);
            split_fxn(123.123, 7);
            split_fxn(1234.123, 7);
            split_fxn(12345.123, 7);
        
            return 0;
        }
        

        EDIT : passé tmp de type double à entier.

        -
        Edité par rouIoude 26 juin 2022 à 17:50:12

        • Partager sur Facebook
        • Partager sur Twitter
        ...
          26 juin 2022 à 17:51:23

          @rouIoude: j'avais oublié cela ...
          On peut décider du nombre de digits avant ou après le point:
              printf("%*.*lf", 8, 5, a);
          Si la partie entière est trop grande, printf affiche plus grand.
          • Partager sur Facebook
          • Partager sur Twitter

          Le Tout est souvent plus grand que la somme de ses parties.

            26 juin 2022 à 17:54:23

            Effectivement, ça ne fonctionne pas si les nombres sont trop grand.
            • Partager sur Facebook
            • Partager sur Twitter
            ...
              26 juin 2022 à 18:40:29

              Je voudrais juste ajouter que le code de rouIoude est nettement plus rapide que log10()
              • Partager sur Facebook
              • Partager sur Twitter

              Le Tout est souvent plus grand que la somme de ses parties.

                26 juin 2022 à 19:00:45

                Amélioration : il faut penser aux nombre négatif 

                #include <stdio.h>
                
                void split_fxn(double number, int nbdigit, int shift)
                {
                    int integral_part = 0;
                    int tmp=number;
                    if (tmp<0) tmp = -tmp;
                    while(tmp>9)
                    {
                        tmp=tmp/10;
                        integral_part++;
                    }
                    nbdigit = nbdigit-integral_part-1;
                
                    if(nbdigit<0) nbdigit=0;
                
                    printf("%*.*f\n", shift, nbdigit, number);
                }
                
                int main(void)
                {
                    split_fxn(-9.9999, 7, 12);
                    split_fxn(-10.0, 7, 12);
                    split_fxn(-0.123, 7, 12);
                    split_fxn(1.123, 7, 12);
                    split_fxn(12.123, 7, 12);
                    split_fxn(123.123, 7, 12);
                    split_fxn(1234.123, 7, 12);
                    split_fxn(-12345.123, 7, 12);
                    split_fxn(123456.123, 7, 12);
                    split_fxn(1234567.123, 7, 12);
                    split_fxn(12345678.123, 7, 12);
                    split_fxn(123456789.123, 7, 12);
                    split_fxn(1234567890.123, 7, 12);
                
                    return 0;
                }



                • Partager sur Facebook
                • Partager sur Twitter
                ...
                  26 juin 2022 à 20:53:33

                  Et si au lieu de fixer le nombre de chiffres à afficher, ont laissait plutôt le programme s'en charger. Dans ce cas, il faudrait :

                  • stocker tous les nombres à afficher dans un tableau de double
                  • trouver le nombre ayant la plus grande partie entière (greatest par exemple)
                  • et enfin, toujours afficher au plus N + 3 chiffres (N étant le nombre de chiffres que contient la partie entière de greatest)

                  Je pense que cela résoudrait le problème que pose le fait d'avoir une partie entière trop grande.

                  Ainsi, pour un tableau

                  double table[3] = {12.34567, 8.25, 512.9648};

                  On aurait:

                  12.3456
                  8.25000
                  512.964

                  Quels sont vos avis ?

                  @rouloude: J'aime beaucoup le fait de prendre en compte les nombres négatifs. Mais dans ce cas, on devra modifier le printf pour qu'il ajoute un plus(+) devant les nombres positifs. En effet, mon but est d'afficher plusieurs nombres sous forme d'un tableau. voici le résultat que j'ai obtenu avec ma fonction split_fxn().

                  NB: il y a quelques tabulations derrière

                  Comme tu peux le voir il y a un alignement parfait des nombres et je souhaite le garder. D'où mon envie de fixer le nombre de chiffres à afficher dès le départ.

                  Etant donné que l'exercice lui-même n'a rien à voir avec le monde de la programmation, j'ai préféré vous épargner les détails.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 juin 2022 à 20:57:18

                    Afficher un nombre de chiffres significatifs si on veut être exact n'est pas simple, il y a aussi les arrondis à prendre en compte.
                    Si on prend l'algo de rouloude, il va faillir dans ce cas.

                    split_fxn(9.94,2,4);   // va bien donner " 9.9"

                    split_fxn(9.96,2,4);   // va donner "10.0" qui a 3 chiffres significatifs!

                    Ces cas étants rares, on peut surement accepter ce "défaut", le résoudre n'est pas si simple.

                    Edit  : en fait il suffit de détecter qu'il y a eu dépassement et d'enlever le chiffre de trop qui est forcément un '0' dans ce cas.

                    -
                    Edité par Dalfab 26 juin 2022 à 21:07:10

                    • Partager sur Facebook
                    • Partager sur Twitter

                    En recherche d'emploi.

                      27 juin 2022 à 0:56:31

                      And if the greatest is really GREAT!
                      Par exemple 1.0e240 ...
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Le Tout est souvent plus grand que la somme de ses parties.

                        27 juin 2022 à 15:19:50

                        Bon, prenons plutôt le problème sous cet angle.

                        J'aurais peut être dû commencer par là mais je suis étudiant en ingénierie pétrolière et dans notre domaine, les nombres les plus grands qu'on obtient sont les quantités d'hydrocarbures. Celles-ci étant toujours estimées en millions de barils, on peut donc prendre cela comme point de référence. Ainsi, on est sûr de toujours avoir au plus 9 chiffres dans la partie entière (MAX = 999,000,000).

                        En utilisant la méthode proposée par @rouloude, il suffirait donc d'afficher exactement 10 chiffres, parties entières et décimales inclues. Mais ça fait beaucoup de zéros pour les nombres plus petits.

                        # Vite fait, ça donne ça

                        Bien entendu cela ne résout pas le problème d'un point de vue général mais dans ce domaine précis, ça pourrait faire l'affaire.

                        Quels sont vos avis ?

                        -
                        Edité par ChristianAlbertLamy 27 juin 2022 à 15:50:01

                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 juin 2022 à 17:11:07

                          Tu pourrais afficher les nombres en format 'e'.
                          Par exemple,
                              printf("%14.9e\n", a);
                          Le nombre de chiffres significatifs serait toujours le même.

                          En fait, si j'ai 999999999 avec le format %15.9e, j'obtiens:
                          9.999999990e+08                                                                                                        

                          -
                          Edité par PierrotLeFou 27 juin 2022 à 17:28:58

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Le Tout est souvent plus grand que la somme de ses parties.

                            27 juin 2022 à 20:17:14

                            Hello,

                            Ceci peut-il aider ?

                            #include <stdio.h>
                            #include <stdlib.h>
                            
                            
                            #define INT_PART_MAX 9
                            #define DEC_PART_MAX 3
                            
                            
                            void dsp(double d) {
                            	long pe=d;
                            	long pd=labs((d-pe)*1000.);    // 1000. = 10. exp DEC_PART_MAX
                            	printf("%*ld.%*0ld\n",INT_PART_MAX,pe,DEC_PART_MAX,pd);
                            }
                            
                            
                            int main(void) {
                            	dsp(-9.9999);
                                dsp(-10.0);
                                dsp(-0.123);
                                dsp(1.123);
                                dsp(12.123);
                                dsp(123.123);
                                dsp(1234.123);
                                dsp(-12345.123);
                                dsp(123456.123);
                                dsp(1234567.123);
                                dsp(12345678.123);
                                dsp(123456789.123);
                            	
                            	return(0);
                            }


                            Edit: Oooups. Je m'aperçois qu'il y a un petit problème avec -0.123

                            -
                            Edité par edgarjacobs 27 juin 2022 à 20:42:45

                            • Partager sur Facebook
                            • Partager sur Twitter

                            On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                              27 juin 2022 à 20:59:34

                              Ça fait de l'alignement sur la virgule (le point). avec trois chiffres derrière.

                              void dsp(double d)
                              {
                                  printf("%15.3f\n", d);
                              }

                              Fait à peut près la même chose !

                              • Partager sur Facebook
                              • Partager sur Twitter
                              ...
                                27 juin 2022 à 22:46:51

                                rouIoude a écrit:

                                Ça fait de l'alignement sur la virgule (le point). avec trois chiffres derrière.

                                void dsp(double d)
                                {
                                    printf("%15.3f\n", d);
                                }

                                Fait à peut près la même chose !

                                Mais oui. Que je suis parfois idiot !

                                • Partager sur Facebook
                                • Partager sur Twitter

                                On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                                Affichage d'un nombre flottant

                                × 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