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

Langage C++ Discussion :

Cast vers un type plus grand et perte de precision


Sujet :

Langage C++

  1. #1
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut Cast vers un type plus grand et perte de precision
    Bonjour.

    Une question me taraude depuis un certain temps :

    Considérons deux façons d'effectuer un calcul :

    Possibilité 1 :
    1) données en double precision
    2) application d'une fonction sur ces données ou tous les types temporaires sont des doubles
    3) retour du resultat en double precision


    Possibilité 2 :
    1) données en double précision
    2) cast des données vers des long double
    3) application d'une fonction sur ces données ou tous les types temporaires sont des long double
    4) cast du résultat de long double vers un double
    5) retour du résultat en double precision


    A la fin j'aurai le même nombre de chiffres après la virgule. Cependant, il peut y a avoir des différences dans le résultat. La question que je me pose est la suivante :

    Est-ce que la 2ème façon de procéder peut donner un résultat plus éloigné du résultat analytique que la 1ère et si oui dans quel cas par exemple ?

    Merci beaucoup.

    PS : sur la plateforme que j'utilise : sizeof(float) = 4, sizeof(double) = 8, sizeof(long double) = 16

  2. #2
    screetch
    Invité(e)
    Par défaut
    question complexe, quelques elements de reponse ici:



    http://randomascii.wordpress.com/201...int-precision/

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 408
    Points : 23 803
    Points
    23 803
    Par défaut
    Citation Envoyé par Kaluza Voir le message
    A la fin j'aurai le même nombre de chiffres après la virgule. Cependant, il peut y a avoir des différences dans le résultat. La question que je me pose est la suivante :

    Est-ce que la 2ème façon de procéder peut donner un résultat plus éloigné du résultat analytique que la 1ère et si oui dans quel cas par exemple ?
    Dans l'absolu, oui. On peut très bien imaginer, dans le même esprit, de 1) partir d'un int, le convertir en double, faire les calculs et re-convertir le résultat en entier ou 2) faire tous les calculs directement sur des entiers. On imagine bien que dans le second cas, chaque fois que le résultat d'une opération ne sera pas entier, on perdra de l'information.

    Sinon, les principaux cas concernés sont ceux où les erreurs se cumulent. Par exemple, avec une progression géométrique de raison irrationnelle, ou lors d'exponentiations successives.

    Voici un exemple ou je pars de 1,2, soit légèrement en dessous de 10^(1/10). C'est une valeur intéressante parce qu'elle est finie en décimale mais pas en binaire. Il y a donc un arrondi qui est appliqué, donc une imprécision qui peut se propager.

    J'affecte cette valeur à un double « x » et je copie celui-ci dans un long double « y ». Ils sont donc censés contenir la même configuration de bits, comblée par des zéros dans le second cas. Je les multiplie ensuite dix fois par eux-mêmes. J'affiche les deux résultats, puis je convertis y en double et j'affiche également le résultat de la conversion.

    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
    21
    22
    #include <stdio.h>
     
    int main (void)
    {
        int i;
        double x;
        long double y;
     
        x = 1.2;
        y = x;
     
        printf ("x start  : %f\n",x);
        for (i=0;i<10;++i) x *= x;
        printf ("x end    : %f\n",x);
     
        printf ("y start  : %Lf\n",y);
        for (i=0;i<10;++i) y *= y;
        printf ("y end    : %Lf\n",y);
        printf ("y double : %f\n",(double)y);
     
        return 0;
    }
    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ ./calcul
    x start  : 1.200000
    x end    : 1206690664274127185924980567972900085846591379277237189994378260649628705381941248.000000
    y start  : 1.200000
    y end    : 1206690664274112834451295821409252676013494557525139169940684154178653027569762304.000000
    y double : 1206690664274112863453313644195509168994826400098441820261403785970498119088996352.000000

    Malgré un type initial plus précis, le long double converti en double affiche un résultat différent du double seul. Et pourtant, dix itérations de x², c'est loin d'être exceptionnel, surtout en astrophysique.

    C'est important parce qu'un simple float est déjà censé être suffisant en soi pour la plupart des cas courants et utiliser double à tout bout de champ n'a réellement cessé d'être pénalisant qu'avec l'arrivée des machines 64 bits. La plupart des gens le faisaient quand même systématiquement par défaut, d'une part parce que c'est le type par défaut utilisé par le C lorsqu'on utilise des constantes décimales, ensuite parce que la plage couverte par un double a l'air tellement immense vue comme ça qu'on était persuadé que s'il y avait de légers risques avec des float, ils auraient complètement disparu avec les double.

    Travailler avec des long double est vorace en ressources, donc autant être sûr de ce qu'on fait à l'avance ! :-)

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Au delà de la représentation, ça ne demande pas d'avoir auparavant fait une analyse de stabilité numérique des fonctions appelées ? De mémoire, des petites erreurs peuvent parfois avoir des effets désastreux sur la convergence des résultats et il vaut mieux parfois partir d'éléments moins précis.

Discussions similaires

  1. Transtyper vers un type plus spécialisé
    Par oodini dans le forum C#
    Réponses: 2
    Dernier message: 11/05/2011, 18h04
  2. Réponses: 25
    Dernier message: 11/08/2010, 16h54
  3. Copie d'1 Memo vers un autre plus grand
    Par Cyrille36 dans le forum Débuter
    Réponses: 4
    Dernier message: 01/07/2009, 13h31
  4. cast d'un objet vers des types dynamiques
    Par aymen007 dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 25/06/2008, 10h31
  5. Cast de variante vers le type long
    Par randriano dans le forum Visual C++
    Réponses: 6
    Dernier message: 08/04/2008, 11h37

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