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

  1. #1
    Membre régulier Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    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 sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    En C standard, je ne vois que atof() et strtod().

  3. #3
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 947
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 947
    Points : 5 660
    Points
    5 660
    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 éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    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 éminent sénior
    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
    Points : 13 926
    Points
    13 926
    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 947
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 947
    Points : 5 660
    Points
    5 660
    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
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    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

  8. #8
    Membre régulier Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    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

  9. #9
    Membre régulier Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    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,

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

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    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

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    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

  12. #12
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    je n'ai pas mis

    mais

    et pour la lecture, je ferais (je ne sais ce que fais exactement atof)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    float f1 ;
    double f ;
     
    sscanf (buffer, "%f", &f1 );
    f = f1 ;
    [EDIT] Ne pas tenir compte de ce post , en tous cas sa 2ième partie
    [/EDIT]

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    Par défaut
    Mon problème est de savoir si il existe un formattage capable de considéré:
    un signe - cinq chiffres dans la partie entiere - sept chiffres dans la partie decimale
    sans qu'il n'y ait de perte de donnée donc sans arrondi.

  14. #14
    Membre régulier Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    Par défaut
    ok, désolé voici le résultat avec %f16.7

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

  15. #15
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    + pour avoir le signe

    5 chiffres + 7 decimales + 1 point + 1 signe = 14

    donc

    %+14.7f ou %+f14.7

    [NOTE]
    là je suis sous Windows. Je bascule sous Linux et revient dans 5 minutes après test

    [/FIN NOTE]

  16. #16
    Membre régulier Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    Par défaut
    avec ce format j 'obtient 0.0000000 ?

  17. #17
    Membre régulier Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    Par défaut
    en fait c est le atof() qui remplissait le double...
    sscanf ne le remplit que si le format est correct.
    %f donne 0.0000
    %lf donne -789.123457
    %+14.7f donne 0.0000
    %lf.7 donne -789.123457
    %+f14.7 donne 0.0000

  18. #18
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    bon voilà, c'est bien ce que je disais :

    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
      char chaine[] = "-759.1234567" ;
      double d ;
     
      sscanf ( chaine, "%lf", &d);
     
      fprintf ( stderr, "chaine [%s] double [%f] [%+14.7f]", chaine , d,d);
     
    return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ./test3
    chaine [-759.1234567] double [-759.123457] [  -759.1234567]

  19. #19
    Membre régulier Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    Par défaut
    ok en fait le probleme de formattage ne vient pas du sscanf mais du printf ,
    MERCI

  20. #20
    Membre régulier Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    Par défaut
    Oui en plus tu me l'a dis plus haut ... désolé il est tard !
    Merci Souviron34 .

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

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