none
Convertion String to Double RRS feed

  • Question

  • Bonjour,

    je suis en train de faire un programme en C sous Visual Studio .net 2008

    j'essaie de convertir un chaine de type string en double...mais je suis surpris du résultat :

    "45.8"  -> 45.7999999999

    "168.4" -> 168.400000001

    avec atof, strotod, sscanf j'obtiens le même résultat.

    Quelqu'un a t il une explication ?

    merci

    jeudi 3 mai 2012 07:39

Réponses

  • Méthode très con, si vous ne faite que des calculs avec un seul chiffre significatif avec après la virgule :

    Vous utilisez que des int ou des long avec des valeurs correspondant à 10 fois la valeur concrète.

    Vous faite tous vos calculs sur des int/long, et vous faites des moulinettes d'affichage qui affiche 45,8 quand la valeur de la variable est 458, etc...

    C'est une sorte de représentation en virgule fixe.

    Mais attention aux approximations/erreurs qui vont vite apparaître lors des calculs qui seront tronqué car n'utiliseront que la partie entière des résultats.

    Vous pouvez aussi représentez les nombres comme une séries de caractères "chiffres" et utiliser des routines qui n'utilise pas les floats ou des doubles mais cette liste. Là vous oubliez les accélérations matérielles des coprocesseurs arithmétiques car c'est votre programme qui gérera la propagation de la retenu, et tout ça. Mais des implémentations pour les calcules mathématiques existes qui prennent ce principe, en plus de la gestion des fractions et tout le toutime.

    Pourquoi sous DOS il n'y a pas de souci ? Peut-être que borland n'utilise pas une représentation à virgule flottante de IEEE (c'est vieux borland et pas très à cheval sur les normes). L'utilisation de la virgule flottante n'est pas une obligation de la norme C (et peut-être même de la norme C++), donc des doubles ou des floats C ne sont pas forcement en virgule flottante.

    Il peut avoir aussi le double bug compensateur, Borland stocke et donc approxime comme VS en virgule flottante mais la routine d'affichage de Borland peut être configuré pour n'afficher qu'1 seul chiffre après la virgule avec approximation en excès.

    etc...


    Paul Bacelar, Ex - MVP VC++

    • Marqué comme réponse Sioloki vendredi 4 mai 2012 08:22
    jeudi 3 mai 2012 16:38
    Modérateur

Toutes les réponses

  • essai  tondouble parseDouble(tonstring). 

    ou en static

    jeudi 3 mai 2012 09:49
  • N'oubliez pas que la représentation des nombres décimaux sur un ordinateur passe par une normalisation en virgule flottante IEEE.

    Ne cherchez pas le bug, c'est normal.

    Si vous voulez "45,8" précisément et non son approximation en virgule flottante, ne passez pas par des double float ou tout autre type exotique basé sur une représentation en virgule flottante.


    Paul Bacelar, Ex - MVP VC++

    jeudi 3 mai 2012 11:19
    Modérateur
  • Le type double a au moins 15 chiffres significatifs, mais pas beaucoup plus. Il n'est pas possible de stocker un nombre infini de décimales. Ce résultat est attendu.

     La précision est à 10-15. Je pense juste que vous avez oublié quelques 9 dans 45.799999999999999 car il devrait y avoir au moins 13 "9" après la virgule.

    jeudi 3 mai 2012 11:23
    Auteur de réponse
  • Ce qui m'étonne c'est que je n'ai pas le souci avec borland sous DOS. Je me doute bien que c'est normal mais je voulais juste avoir le pourquoi.

    "

    Si vous voulez "45,8" précisément et non son approximation en virgule flottante, ne passez pas par des double float ou tout autre type exotique basé sur une représentation en virgule flottante."

    j'utilise quoi à la place?? 45.8 contient une virgule donc pour moi c'est un float ou un double.

    jeudi 3 mai 2012 12:24
  • Méthode très con, si vous ne faite que des calculs avec un seul chiffre significatif avec après la virgule :

    Vous utilisez que des int ou des long avec des valeurs correspondant à 10 fois la valeur concrète.

    Vous faite tous vos calculs sur des int/long, et vous faites des moulinettes d'affichage qui affiche 45,8 quand la valeur de la variable est 458, etc...

    C'est une sorte de représentation en virgule fixe.

    Mais attention aux approximations/erreurs qui vont vite apparaître lors des calculs qui seront tronqué car n'utiliseront que la partie entière des résultats.

    Vous pouvez aussi représentez les nombres comme une séries de caractères "chiffres" et utiliser des routines qui n'utilise pas les floats ou des doubles mais cette liste. Là vous oubliez les accélérations matérielles des coprocesseurs arithmétiques car c'est votre programme qui gérera la propagation de la retenu, et tout ça. Mais des implémentations pour les calcules mathématiques existes qui prennent ce principe, en plus de la gestion des fractions et tout le toutime.

    Pourquoi sous DOS il n'y a pas de souci ? Peut-être que borland n'utilise pas une représentation à virgule flottante de IEEE (c'est vieux borland et pas très à cheval sur les normes). L'utilisation de la virgule flottante n'est pas une obligation de la norme C (et peut-être même de la norme C++), donc des doubles ou des floats C ne sont pas forcement en virgule flottante.

    Il peut avoir aussi le double bug compensateur, Borland stocke et donc approxime comme VS en virgule flottante mais la routine d'affichage de Borland peut être configuré pour n'afficher qu'1 seul chiffre après la virgule avec approximation en excès.

    etc...


    Paul Bacelar, Ex - MVP VC++

    • Marqué comme réponse Sioloki vendredi 4 mai 2012 08:22
    jeudi 3 mai 2012 16:38
    Modérateur