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 :

Cos et sin de math.h ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 65
    Par défaut Cos et sin de math.h ?
    Bonjour,

    J'ai remarqué quelque chose et j'aimerais savoir si c'est normal.

    je définis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const double pi = 3.1415926535897932384626433832795028841968;
    puis je calcule

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout<<cos(0)<<"\n"<<sin(0)<<"\n"<<cos(pi/2)<<"\n"<<sin(pi/2)<<"\n";
    Pour sin(pi/2), il me donne 1, mais pour cos(pi/2), j'obtiens une valeur approchée en 10^(-17). Moi je m'attendais, pour le sinus, à obtenir une valeur approchée de 1, en 0.99999999... puisque j'ai donné une valeur arrondie pour pi.

    Conclusion : je ne comprends pas pourquoi il me donne une valeur arrondie pour l'une des fonctions et pas pour l'autre.

    Quelqu'un a-t-il déjà remarqué le phénomène et si oui, pourrait-il m'expliquer ?
    (je pense que ce doit être à la fois une histoire de codage des nombres sur les ordinateurs, et également la façon dont sont définies les méthodes de calcul des cosinus et sinus)

    Cordialement

  2. #2
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Bonjour,
    C'est surtout une question de précision.

    On ne peut pas stocker une infinité de décimales, donc on les limite.
    Et franchement, je ne pense pas qu'en C/C++ on puisse stocker un nombre avec une précision aussi grande, même avec un long double.
    (Peut-être avec un long long double ?).
    Donc la valeur de ta variable est tronquée par rapport à celle que tu donnes.

    Ensuite, ce n'est pas étonnant d'avoir des erreurs de calcul lorsque l'on travaille avec des approximations.
    Parfois, une toute petite approximation peut donner un écart très important au final.

    Mais bon, quand tu as une valeur arrondie en 10^-17, c'est certainement que le résultat était 0.
    Mais dis-moi, cos(PI/2), ça ne ferait pas 0, justement ?

    En passant, PI est déjà définie dans l'en-tête math.h.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    # define M_PI		3.14159265358979323846	/* pi */
    # define M_PI_2		1.57079632679489661923	/* pi/2 */
    # define M_PI_4		0.78539816339744830962	/* pi/4 */
    # define M_1_PI		0.31830988618379067154	/* 1/pi */
    # define M_2_PI		0.63661977236758134308	/* 2/pi */
    # define M_2_SQRTPI	1.12837916709551257390	/* 2/sqrt(pi) */
    Ces valeurs peuvent être définies en long double, selon les options du compilateur.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Quelle que soit la base envisagée, il y a toujours des valeurs que l'on ne peut définir qu'avec une certaine imprécision:

    • En base dix (vu que c'est celle que l'humain est le plus habitué à manipuler ), on trouve des valeurs comme 1/3 (0,33333333...), pi (3.1415926....) et bien d'autres encore
    • En base 2(ce qui est la base utilisée dans un ordinateur), l'imprécision est différente, parce que la représentation des valeurs est simplement différente.
    De plus, la conversion elle-même de l'un en l'autre peut être source d'imprécision (parce que certaines valeurs en base dix ne peuvent simplement pas être représentées de manière finie en base deux, et inversement).

    En outre, si tu peux envisager de rajouter "un chiffre" à une valeur décimale que tu écris toi-même "tant que tu la connais et que tu en a le courrage" (je me suis arrêté à sept chiffres derrière la virgule pour pi, alors que tu es allé beaucoup plus loin ), il faut retenir le fait que le processeur est limité par la place qu'il peut utiliser pour représenter les différents types.

    Cela signifie qu'il ne peut utiliser qu'un certain nombre de bits pour la mantisse et un autre nombre de bits pour l'exposant.

    Et cela implique qu'il ne dispose que d'une plage de valeurs bien précise, définie et finie pour représenter les valeurs qu'on veut lui soumettre.

    Ajoute à cela qu'une norme a défini "plus ou moins arbitrairement" la précision que les différents types doivent respecter, les règles d'arrondi qui sont, quoi qu'il arrive, à respecter et le fait que nous observons deux conversions entre le code que l'on écrit et la valeur que l'on fait afficher (la valeur en base dix que l'on écrit est convertie en base deux, avec un premier risque d'imprécision, puis la valeur connue par le processeur est convertie en base dix pour l'affichage, avec un nouveau risque d'imprécision ) et tu comprendra aisément qu'il puisse y avoir certaines différences dans les valeurs obtenues pour certaines opérations dont le résultat est "remarquable" .

    En effet, quelle que soit la précision que l'on veuille appliquer à la valeur 0.999999999999999999999 (par exemple: 8 chiffres après la virgule), les règles d'arrondi nous disent que le dernier chiffre significatif doit être arrondi à l'unité supérieure (car le chiffre suivant est 9).

    Ce passage à l'unité supérieure du dernier chiffre significatif va faire passer celui-ci à 0 et va provoquer le passage du chiffre qui le précède à... l'unité supérieure, et ainsi de suite, jusqu'à arriver à l'unité (le 0), qui passe à un, moment où tout s'arrête enfin

    Si cela se trouve, l'arrondi du dernier chiffre significatif pour la valeur de cos(pi/2) ne doit pas passer à l'unité supérieur (parce que le chiffre qui suit est inférieur ou égal à 4), à moins qu'il n'y ait, simplement, entre l'unité et le dernier chiffre significatif, un chiffre qui ne retourne pas à 0 en passant à l'unité supérieure, ou une imprécision dans le calcul qui fait que ou... va savoir...

    Toujours est il que c'est la raison pour laquelle il faut être particulièrement prudent lorsque l'on manipule des valeurs réelles, et qu'il faut intégrer l'idée d'une certaine imprécision dans la logique que l'on va tenter de mettre en oeuvre lorsqu'on les manipule.

    C'est d'ailleurs pour cela qu'un compilateur correctement réglé devrait, normalement, t'indiquer que l'égalité entre deux réels est toujours fausse si, a et b étant des réels (dont au moins un est calculé), tu tentes un test proche de a==b .
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 65
    Par défaut
    Merci pour toutes vos réponses.

    Joyeuses fêtes à tous.

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 05/01/2010, 09h57
  2. Besoin d'une petite précision pour exp, cos et sin.
    Par UiYuki dans le forum Mathématiques
    Réponses: 1
    Dernier message: 17/10/2008, 23h22
  3. Fonctions cos et sin en VB6
    Par bob74500 dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 01/04/2008, 20h59
  4. [Math] Utiliser cos, sin, log ou les programmer ?
    Par zaim dans le forum Langages de programmation
    Réponses: 3
    Dernier message: 13/04/2006, 20h49
  5. aide fonction math[racine,cos(),sin(),..]VB6
    Par am.adnane dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 28/12/2005, 18h40

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