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 :

Petit soucis avec les doubles


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut Petit soucis avec les doubles
    Bonjour,
    je dois convertir en double la chaine stockée à l'adresse buffer,
    j'ai pensé à atof()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    double d;
    d = atof(buffer);
    Le problème est que ma chaine comporte une partie entière signée non nulle et plus de cinq décimales significatives:
    -789.1234567
    Comment puis-je réaliser une telle conversion sans perdre d'informations?
    Est ce qu il existe une structure qui me permettrai de faire des calculs avec une telle précision ?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    En C standard, je ne vois que atof() et strtod().
    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.

  3. #3
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Mea,

    Les double, avec 64 bits pour leur représentation, donnent environ 16 chiffres significatifs,

    MAIS

    il faut savoir qu'ils sont très loin de pouvoir représenter n'importe quelle valeur entrant dans leur gamme de représentation.
    En fait, l'ensemble des valeurs représentables exactement est très petit par rapport à la gamme de valeurs acceptées par la représentation.

    Il n'y a donc pas de réponse à ta question, tu ne pourras pas conserver la valeur exacte donnée par ta chaîne, sauf pour un "petit" ensemble de valeurs.

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par droggo Voir le message
    Il n'y a donc pas de réponse à ta question, tu ne pourras pas conserver la valeur exacte donnée par ta chaîne, sauf pour un "petit" ensemble de valeurs.
    euh !!

    5 chiffres après la vigule ??





    DBL_ESPILON est de l'ordre de 10^-13 à 10^-17.

    qu'est-ce que tu racontes ??

    N'importe quel double peut stocker n'importe quelle information jusqu'à 1.2e+308, à la précision sus-dite.

    Donc, pour répondre à la question du PO, ce que cite Médinoc est tout à fait correct..

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    souviron34 :
    Citation:
    Envoyé par droggo
    Il n'y a donc pas de réponse à ta question, tu ne pourras pas conserver la valeur exacte donnée par ta chaîne, sauf pour un "petit" ensemble de valeurs.
    euh !!

    5 chiffres après la vigule ??
    Le nombre de chiffres après la virgule n'entre pas en ligne de compte. Seul le nombre de chiffres significatifs compte

    La remarque de droggo est correcte :
    tu ne pourras pas conserver la valeur exacte
    Ce qui n'empeche pas que la réponse de Medinoc soit correcte

  6. #6
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Fai,
    Citation Envoyé par souviron34 Voir le message
    euh !!

    5 chiffres après la vigule ??





    DBL_ESPILON est de l'ordre de 10^-13 à 10^-17.

    qu'est-ce que tu racontes ??

    N'importe quel double peut stocker n'importe quelle information jusqu'à 1.2e+308, à la précision sus-dite.

    Donc, pour répondre à la question du PO, ce que cite Médinoc est tout à fait correct..
    pour continuer sur diogene, le nombre de chiffres après la virgule n'a rien à voir.

    On dispose au total d'environ 16 chiffres significatifs.

    Essaye de stocker 123456789012345678901234567890123.12345, et reviens me montrer ce qu'il restera des décimales, qui ne sont pourtant que 5, et même d'une bonne partie de la partie entière.

  7. #7
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    euh !!

    5 chiffres après la vigule ??





    DBL_ESPILON est de l'ordre de 10^-13 à 10^-17.

    qu'est-ce que tu racontes ??

    N'importe quel double peut stocker n'importe quelle information jusqu'à 1.2e+308, à la précision sus-dite.
    Pas du tout, par exemple 0.09 ne peut pas être stocké.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <stdio.h>
     
    int main (void)
    {
       printf("%.20f\n", 0.09);
       return 0;
    }
    Sortie :

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    et si tu regardes ta sortie, tu demandes 20 décimales, ce qui est supérieur à la précision.

    Fait .15 et tu verras ;-)

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par yakamoneye Voir le message
    Le problème est que ma chaine comporte une partie entière signée non nulle et plus de cinq décimales significatives:
    -789.1234567
    On dispose au total d'environ 16 chiffres significatifs.
    %f16.7

    marchera parfaitement

    de même que

    %.7g

  10. #10
    Membre éprouvé Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut
    %f16.7

    marchera parfaitement

    de même que

    %.7g
    Bonsoir Souviron34, est ce que tu peux détailler...
    est il possible de faire un ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sscanf (buffer, "%16.7lf", &d);
    ?
    J'essaie et si ça marche, je suis vert de ne pas y avoir pensé avant

  11. #11
    Membre éprouvé Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut
    Voila le 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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main (void)
    {
     char buffer[56];
     strcpy(buffer,"-789.1234567");
     printf("%s\n",buffer);
     double d=atof(buffer);
     printf("%f\n",d);
     sscanf(buffer,"%16.7lf",&d);
     printf("%f\n",d);
     return 0;
    }
    et voila le résultat

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    [yakamoneye@localhost ~]$ ./a.out
    -789.1234567
    -789.123457
    -789.123457
    toujours une perte d'information,

  12. #12
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par yakamoneye Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sscanf (buffer, "%16.7lf", &d);
    Pas standard ça! ça compile chez toi?
    Pour rappel la syntaxe des codes de format des fonctions de la famille scanf est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    %[*][gabarit][h/l/L]conversion

  13. #13
    Membre éprouvé Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut
    Oui, ça compile et ça s'execute sinon je n'aurai pas d'affichage.
    Merci pour le rappel, j'avoue que je nage un peu sur le formattage des fonctions de la famille scanf...
    Mais en même temps le man n'est pas trés clair

  14. #14
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par yakamoneye Voir le message
    Voila le code...

    toujours une perte d'information,
    Bah oui, si on ne sait pas utiliser printf(), c'est pas gagné... Faut lire la doc de temps en temps, ça aide...

    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main (void)
    {
       char buffer[]="-789.1234567";
       printf ("%s\n", buffer);
     
       double d = atof (buffer);
       printf ("%.7f\n", d);
     
       d = strtod (buffer, NULL);
       printf ("%.7f\n", d);
     
       sscanf (buffer, "%lf", &d);
       printf ("%.7f\n", d);
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    -789.1234567
    -789.1234567
    -789.1234567
    -789.1234567
     
    Press ENTER to continue.

  15. #15
    Membre éprouvé Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut
    Bah oui, si on ne sait pas utiliser printf(), c'est pas gagné... Faut lire la doc de temps en temps, ça aide...
    La critique est facile ... surtout dans le forum "Débuter" ...

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

Discussions similaires

  1. Petit souci avec les dialogues
    Par Teaniel dans le forum BOUML
    Réponses: 4
    Dernier message: 23/07/2011, 15h29
  2. Un petit souci avec les dates
    Par Ben-o dans le forum SQL Procédural
    Réponses: 11
    Dernier message: 27/09/2007, 18h42
  3. Réponses: 10
    Dernier message: 26/10/2006, 12h25
  4. petit soucis avec les listes
    Par Death83 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 03/09/2005, 10h08

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