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 :

Problème de précision Visual C++ sous win


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 62
    Par défaut Problème de précision Visual C++ sous win
    Bonjour,

    j'ai posté hier pensant avoir un pb dans mon programme et en fait cela ne vient pas de moi.
    Voilà j'ai codé une appli C/C++ sur snowleopard avec Xcode et tout marchait pour le mieux.
    En recondant le tout sous visual C++, bizarre, résultats aberrants.
    En affinant mes recherches, j'ai finalement vu l'endroit ou cela coinçait mais aucune idée pour résoudre le problème.

    Alors voila, j'ai une fonction simple, appelons la f définie comme suit dans mo programme sous Xcode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double f(double x){
    return 0.5*(1-erf(x/sqrt(2)))
    }
    Les fonction C99 et donc 'erf' n'étant pas prises en charge sous VC++, je fais appel à boost, et la fonction reste la même à part que j'appelle boost::math::erf

    Passons ensuite au résultats.
    La fonction erf est une fonction définie sur tout R comme le montre
    http://fr.wikipedia.org/wiki/Fichier:Erf_plot.svg

    Déclarons
    double a = -37.1326;
    double b = -8.26506;
    double ra = f(a);
    double rb = f(b);

    f(a) et f(b) sont donc très proches de 1

    Si je fais des printf("%e", ra) et printf("%e",rb)
    je vais voir s'afficher sur la console 1.000000e+00 sous Xcode et VC++

    Maintenant, faisons la différence
    double dif = f(a)-f(b);
    et printf("%e",dif);

    Sous Xcode on obtient 1.11022e-16, sous VC++ on obtient 0.000000e+000


    VC++ m'enlève donc toute précision en faisant la différence. Mais d'un autre côté, pourquoi Xcode m'enlève-t-il également la précision sur l'affichage séparé de f(a) et f(b) et m'affiche quelquechose de correct pour la différence.

    Toujours est-il que je dois avoir cette précision et que je n'ai pas la solution à ce pb

    Merci a celui qui m'apportera une aide

  2. #2
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    DIfférentes librairies C == différentes manière de gérer la précision du FPU. Sous Visual C++, tu peux utiliser la fonction _controlfp() pour gérer ce point par toi même.

    Ensuite, la question de l'affichage est du domaine du "chacun fait ce qu'il veut". Aucune norme ne précise comment afficher un float ou un double.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 62
    Par défaut
    Ok, donc il existe une solution au problème.. je me doutais que c'était les libs et je me doutais qu'il y avait une solution vu que matlab sous win fait cela sans soucis.
    Merci

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 62
    Par défaut
    Bon j'ai tenté, et je n'y parviens pas.

    Voici le petit bout de 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // PrecisionCalcul.cpp*: définit le point d'entrée pour l'application console.
    //
     
    #include "stdafx.h"
    #include <C:\Program Files (x86)\boost\boost_1_44\boost\math\special_functions\erf.hpp>
    #include <float.h>
    #pragma fenv_access (on)
     
     
    int _tmain(int argc, _TCHAR* argv[])
    {
     
    	unsigned int control_word_x87;
    	control_word_x87 = __control87_2(_PC_24, MCW_PC,&control_word_x87, 0);
     
    	double a = -37.1326;
    	double b = -8.26506;
    	double d = 2;
    	double dd = 0.5;
    	double ra = dd*(1-boost::math::erf(a/sqrt(d)));
    	double rb = dd*(1-boost::math::erf(b/sqrt(d)));
    	double dif = ra- rb;
     
    	printf("ra=%e\n",ra);
    	printf("rb=%e\n",rb);
    	printf("dif=%e\n",dif);
     
    }
    La sortie est toujours la même
    ra=1.000000e+000
    rb=1.000000e+000
    dif=0.000000e+000

    Conclusion je ne sais pas comment utiliser ce que tu viens de me donner...

  5. #5
    Membre extrêmement actif

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 401
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 401
    Par défaut
    Sous Xcode on obtient 1.11022e-16, sous VC++ on obtient 0.000000e+000
    techniquement ces 2 valeurs sont identiques, à DBL_EPSILON près bien sur, mais vu qu'on ne compare jamais 2 valeurs flottantes directement entre elles...

    pourquoi as tu besoin de cette "précision"?

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 62
    Par défaut
    J'ai besoin de cette précision car les résultats que je calcule sont des probabilités, en gros une multiplication de 2 différences semblables à celle présentée dans le post plus haut, donc si on m'arrondi mon 0.1e-16 a 0..
    mon 1.1e-16 multiplié par mon 3.48e+15 devient 0.. pas très cool tu l'admettras.
    Ce n'était pas un chipotage pour grignoter quelques chiffres... Cela est indispensable au bon fonctionnement de ce que j'ai fait
    Mais j'ai installé MPIR et MPFR et tout va bien maintenant
    Problème solved.
    Merci

  7. #7
    Membre extrêmement actif

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 401
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 401
    Par défaut
    j'avais lu un article il y a longtemps qui montrait l'aggravation de l'imprécision des flottants sur les opérations simples.

    bonne chance pour tes probas.

Discussions similaires

  1. Réponses: 3
    Dernier message: 20/11/2011, 19h14
  2. Problème avec DataBase Desktop 7 sous Win Vista ?
    Par maker dans le forum C++Builder
    Réponses: 0
    Dernier message: 22/03/2010, 23h11
  3. Probléme de mot de passe sous win server 2003
    Par koKoTis dans le forum Windows Serveur
    Réponses: 5
    Dernier message: 16/09/2007, 14h25
  4. Réponses: 2
    Dernier message: 30/10/2006, 15h25
  5. Réponses: 7
    Dernier message: 27/09/2005, 21h40

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