Partage
  • Partager sur Facebook
  • Partager sur Twitter

Multiplication entre double

    22 septembre 2021 à 15:01:40

    Salut !

    Je rencontre un problème avec la multiplication entre double, l'opération suivante :

    0.42549999999999999 * 1000 = 425.5 au lieu de 425.4

    En recherchant sur Internet, j'ai compris que c'était un problème d'interprétation des doubles. Mais comment y remédier ?

    J'ai déjà essayé plusieurs méthodes : tronquer le double, passer par un string pour le tronquer...

    Mais rien n'y fait, existe t'il une solution ?

    Merci d'avance ! :)

    • Partager sur Facebook
    • Partager sur Twitter
      22 septembre 2021 à 15:41:59

      Pas de solution directe, par construction le type double à une précision limitée et les opérations dessus sont forcément des approximations.

      C'est souvent suffisant mais dans les cas ou l'on a besoin d'une très forte précision il faut soit utiliser un type plus précis comme long double, soit utiliser une bibliothèque de calcul conçue pour comme GMP.

      Il est aussi souvent (toujours ?) possible de revoir son algo pour essayer de se passer au maximum des divisions, prendre en compte les erreurs, travailler avec des entiers etc ... pour ne pas avoir ce genre de problème.

      -
      Edité par Orochi 22 septembre 2021 à 15:42:21

      • Partager sur Facebook
      • Partager sur Twitter
        22 septembre 2021 à 16:09:26

        Merci de ta réponse !

        Eh oui, j'ai essayé de voir d'où venait ce nombre.. il vient de l'utilisation de la méthode _wtof pour transformer un CString en double.

        Le CString contient juste "6.35" avant d'être transformé en "6.3499999999999996"...

        • Partager sur Facebook
        • Partager sur Twitter
          22 septembre 2021 à 17:25:09

          Toniooo a écrit:

          Je rencontre un problème avec la multiplication entre double, l'opération suivante :

          0.42549999999999999 * 1000 = 425.5 au lieu de 425.4

          Et pourquoi ça ferait 425.4 ? le résultat et quand même nettement plus proche de 425.5

          • Partager sur Facebook
          • Partager sur Twitter
            22 septembre 2021 à 17:37:27

            On n'a même pas besoin des ordinateurs pour mal interpréter les fractions:
            Si je fais:
             1 / 3, on dit que ça donne 0.333... à l'infini
            Si je fais:
            1/3 *3, ça devrait donner 1, non?
            Si je fais:
            0.333... * 3, j'obtiens 0.999... à l'infini
            Le hic est que les ordi n'ont pas une précision infinie.
            • Partager sur Facebook
            • Partager sur Twitter

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

              22 septembre 2021 à 20:51:40

              0.999 à l'infini ça fait 1 au final. ;)

              -
              Edité par Warren79 22 septembre 2021 à 20:52:01

              • Partager sur Facebook
              • Partager sur Twitter

              Mon site web de jeux SDL2 entre autres : https://www.ant01.fr

                22 septembre 2021 à 22:36:41

                Zero.c a écrit:

                Toniooo a écrit:

                Je rencontre un problème avec la multiplication entre double, l'opération suivante :

                0.42549999999999999 * 1000 = 425.5 au lieu de 425.4

                Et pourquoi ça ferait 425.4 ? le résultat et quand même nettement plus proche de 425.5

                Tout à fait.

                Le nombre 0.4255 ne peut pas être stocké exactement dans un double, les 2 nombres les plus proches sont 0.425499999999999989341858963598497211933135986328125 et 0.425500000000000044853010194856324233114719390869140625 (ces séquences semblent bizarres mais écrits en base 2, seul 1 bit les différencie.)
                Après multiplication du plus proche (le premier) par 1000. Il y aussi approximation du résultat. Là, coup de bol, le nombre le plus proche représentable dans un double tombe pile sur 425.5. L'erreur apparente a donc disparue, et on est très loin de 425.4.

                Mais donc où est ton soucis Toniooo?

                • Partager sur Facebook
                • Partager sur Twitter

                En recherche d'emploi.

                  23 septembre 2021 à 0:07:58

                  Salut,

                  Les double restent une approximation avec environ 13 chiffres significatifs. 

                  ça veut dire que quand tu écris 425.xxxx    tu as une précision de 10^-11  ce qui est bien non ?

                  Ton problème n'existe qu'au moment de l'affichage. Dans quel contexte as tu ce soucis ?

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                    23 septembre 2021 à 1:37:57

                    Warren79 a écrit:

                    0.999 à l'infini ça fait 1 au final. ;)

                    -
                    Edité par Warren79 il y a environ 4 heures


                    On n'a pas une infinité de digits sur un ordi, même avec des bibliothèques multiple précision.
                    • Partager sur Facebook
                    • Partager sur Twitter

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

                      23 septembre 2021 à 9:16:00

                      Merci pour vos réponses :)

                      En faite, je récupère une valeur réelle dans un CString, ensuite je la convertie en double (car j'ai besoin d'effectuer des opérations dessus).

                      Complètement d'accord avec vous, sur le fait que "0.42549999999999999 * 1000 = 425.5 au lieu de 425.4"

                      Mais j'ai besoin d'afficher la valeur 425.4, pour la faire correspondre exactement avec une autre valeur à 425.4.. je sais c'est bizarre mais malheureusement je n'ai pas le choix >_<

                      Cependant j'ai réussi à régler mon problème en effectuant l'opération dans un type double de boost :)

                      • Partager sur Facebook
                      • Partager sur Twitter
                        23 septembre 2021 à 9:26:22

                        Sinon, si tu veux 2 chiffres apres la virgule, tu multiples par 10, tu tronques (cast en int), puis tu redivises par 10. Et tu auras tes 425.4

                        Par contre, fait attention, si fais par exemple 0.1 * 4, rien n'empêche la machine de donner 0.399999999999

                        Et si tu tronques, tu auras 0.3

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                          23 septembre 2021 à 10:11:32

                          Toniooo a écrit:

                          Mais j'ai besoin d'afficher la valeur 425.4, pour la faire correspondre exactement avec une autre valeur à 425.4.. je sais c'est bizarre mais malheureusement je n'ai pas le choix >_<


                          Tu peux décrire en quelques mots ce que tu veux faire ? Parce que oui, c'est bizarre :D
                          • Partager sur Facebook
                          • Partager sur Twitter
                            23 septembre 2021 à 17:36:40

                            Il n'y a pas que l'affichage. Comparer deux double est hasardeux.
                            Les deux nombres ne diffèrent peut-être que par le dermier bit, le moins significatif.
                            Quand l'ordre de grandeur des nombre le permet, il vaut parfois mieux travailler avec des entiers.
                            • Partager sur Facebook
                            • Partager sur Twitter

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

                              24 septembre 2021 à 1:41:47

                              spotiplus a écrit:

                              On n'a même pas besoin des ordinateurs pour mal interpréter les fractions:
                              Si je fais:
                               1 / 3, on dit que ça donne 0.333... à l'infini
                              Si je fais:
                              1/3 *3, ça devrait donner 1, non?
                              Si je fais:
                              0.333... * 3, j'obtiens 0.999... à l'infini
                              Le hic est que les ordi n'ont pas une précision infinie.


                              Merci de me citer, ça me fait vraiment plaisir. :)

                              Et est-ce que le pot va suivre les fleurs?

                              • Partager sur Facebook
                              • Partager sur Twitter

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

                              Multiplication entre double

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              • Editeur
                              • Markdown