Gros probleme étrange de precision pour les long double

Le
Cédric BILLOT
Voila, je suis sur un projet qui demande énormément de précision, je travail
donc en long double.
Je calcule la dérivé d'une fonction en un point grace a une methode simple
(f(x+h)-f(x-h))/2h) mais voila,
pour 80% des cas tout va bien; et parfois, je me retrouvais avec 0, alors
que la reponse du calcul fait sous Maple donnais un résultat.
J'ai épuré mon code autour de l'erreur jusqu'a avoir le code suivant.

long double h = 0.00000000000000000000001;
long double a = 10132.2;
if(a == a + h) cout<<"ERREUR DE CALCUL."<<endl;

et la!!!! c'est le drame!!!!

en effet a==a+h pourquoi?
Je ne pense pas pourtant arriver a la limite de précision du long double.

Quelqu'un a-t-il la solution a mon problème???

Merci d'avance,
@+Fab
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #710892
"Cédric BILLOT"
long double h = 0.00000000000000000000001;

long double a = 10132.2;
if(a == a + h) cout<<"ERREUR DE CALCUL."<<endl;

et la!!!! c'est le drame!!!!

en effet a==a+h pourquoi?
Je ne pense pas pourtant arriver a la limite de précision du long double....


Si 17-18 chiffres significatifs et il t'en faudrait 28...

A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Cédric BILLOT
Le #710891
long double h = 0.00000000000000000000001;
long double a = 10132.2;
if(a == a + h) cout<<"ERREUR DE CALCUL."<<endl;
et la!!!! c'est le drame!!!!
en effet a==a+h pourquoi?
Je ne pense pas pourtant arriver a la limite de précision du long
double....



Si 17-18 chiffres significatifs et il t'en faudrait 28...
A bon, pourquoi???

La Mantisse est codé sur combien de bit pour le long double?

Merci,
@+Fab


Jan Rendek
Le #710889
Tu dépasses la précision des long double.
Sur ma machine: intel, linux mandrake 9.2, GCC 3.3
La précision est de 10e-19

Une manière simple de le vérifier:

#include <limits>
#include <iostream>
int main()
{
std::cout << std::numeric_limits<long double>::epsilon();
}

--
Jan Rendek
INRIA Lorraine
r e n d e k @ l o r i a . f r
Jean-Marc Bourguet
Le #738992
"Cédric BILLOT"
long double h = 0.00000000000000000000001;
long double a = 10132.2;
if(a == a + h) cout<<"ERREUR DE CALCUL."<<endl;
et la!!!! c'est le drame!!!!
en effet a==a+h pourquoi?
Je ne pense pas pourtant arriver a la limite de précision du long
double....



Si 17-18 chiffres significatifs et il t'en faudrait 28...
A bon, pourquoi???

La Mantisse est codé sur combien de bit pour le long double?


ca depend, 52 64 ou plus (si les long double sont sur 128 bits, je ne
connais ca que sur des stations Unix).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Marco
Le #738671
Jan Rendek wrote:
Tu dépasses la précision des long double.
Sur ma machine: intel, linux mandrake 9.2, GCC 3.3
La précision est de 10e-19

Une manière simple de le vérifier:

#include <limits>
#include <iostream>
int main()
{
std::cout << std::numeric_limits<long double>::epsilon();
}

Quand tu penses que la précision du double est de 2x10^-16 ...

Puis quand tu affiches sizeof(long double) tu obtiens 12 octets contre 8
octets pour le double. Le long double c'est un peu du gadget sur les
machines 32 bits, a mon avis. Si tu veux de la vraie quadruple
précision,soit tu utilises une machine 64 bits, soit tu utilise une
librairie C++ qui gère la précision multiple, style gmp (Gnu Multiple
Precision). D'ailleurs sur cette librairie, je trouve l'interface C++
absolument infame et incompréhensible, et j'ai été bien incapable d e
surcharger la fonction cosinus sur la classe C++ class_mpfr . Si
certaines personnes ont utilisés gmp, avec du C++ et des cosinus, sinus ,
exp et log, je suis preneur :-)

Pierre Maurette
Le #738669
"Cédric BILLOT"
long double h = 0.00000000000000000000001;
long double a = 10132.2;
if(a == a + h) cout<<"ERREUR DE CALCUL."<<endl;
et la!!!! c'est le drame!!!!
en effet a==a+h pourquoi?
Je ne pense pas pourtant arriver a la limite de précision du long
double....



Si 17-18 chiffres significatifs et il t'en faudrait 28...
A bon, pourquoi???

La Mantisse est codé sur combien de bit pour le long double?


Pour info, formats des "réels" de la FPU Intel:
Single Double Extended
bits total 32 64 80
bits exposant 8 11 15
bits mantisse 23 52 63
précision (bits) 24 53 64

La mantisse est positive, l'exposant "biasé", c.a.d en gros signé
centré sur 0.
Si vous faites un contrôle du total des bits, n'oubliez pas le bit du
cygne. Et il n'y a pas d'erreur, l'extended a un format un peu
particulier.

Voir la doc (norme ou bouquin), en particulier les macros de float.h,
par exemple FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON, ...

Pierre



Horst Kraemer
Le #738668
On Thu, 1 Apr 2004 17:32:28 +0200, "Cédric BILLOT"

Voila, je suis sur un projet qui demande énormément de précision, je travail
donc en long double.
Je calcule la dérivé d'une fonction en un point grace a une methode simple
(f(x+h)-f(x-h))/2h) mais voila,
pour 80% des cas tout va bien; et parfois, je me retrouvais avec 0, alors
que la reponse du calcul fait sous Maple donnais un résultat.
J'ai épuré mon code autour de l'erreur jusqu'a avoir le code suivant.

long double h = 0.00000000000000000000001;
long double a = 10132.2;
if(a == a + h) cout<<"ERREUR DE CALCUL."<<endl;

et la!!!! c'est le drame!!!!

en effet a==a+h pourquoi?


Pour garantir que a+h > a il faut que h/a soit supérieur à
LDBL_EPSILON.



Je ne pense pas pourtant arriver a la limite de précision du long double....


Chez moi LDBL_EPSILON vaut 1E-19 et ton h/a vaut environ 1E-27.

Le problème général est que dans un calcul numérique avec des
flottants le quotient (f(a+h)-f(a-h))/2h ne converge pas vers f'(a)
pour h->0 parce que la soustraction de deux valeurs trés proches
détruit la précision du résultat au lieu de l'augmenter.

--
Horst

Alexandre
Le #738667
"Cédric BILLOT" news:c4hd61$sip$
long double h = 0.00000000000000000000001;
long double a = 10132.2;
if(a == a + h) cout<<"ERREUR DE CALCUL."<<endl;
et la!!!! c'est le drame!!!!
en effet a==a+h pourquoi?
Je ne pense pas pourtant arriver a la limite de précision du long
double....




Non, peut-être pas, mais en tout cas la constante est de type double,
elle.... Donc nulle.... Il faut ajouter un suffixe LD
long double h = 0.00000000000000000000001LD;



Si 17-18 chiffres significatifs et il t'en faudrait 28...
A bon, pourquoi???

La Mantisse est codé sur combien de bit pour le long double?

Merci,
@+Fab






Cédric BILLOT
Le #738666
Oui en effet; merci pour vos explication ;-)
Par contre comment je pourais m'en sortir pour avoir la meilleur
précision???
-Utilisé un h plutôt gros???
-Utilisé un h calculé en fonction de je ne sais pas trop koi??
En gros j'ai besoin d'une précision assez importante, et ma fonction qui
fait des dérivés partiels est utilisé plein de fois pour remplire une
matrice de taille 500*5 donc je ne peut pas me permettre non plus de perdre
trop de temps....
Est-ce qu'il existe un type de précision superieur au long double ???
Vous avez parlé du type Extended, je l'avais utilisé dans ma jeunesse, mais
je ne sais plus le faire (y-a-t-il un .h a inclure...).

Pour info j'utilise VC++ 6 et aussi Borland C++ 6 Builder (d'ailleur, c'est
surtout sous ce dernier que j'aimerais résoudre ce problème).
Je suis sur machine x86 sous Win2k.

@+Fab



Voila, je suis sur un projet qui demande énormément de précision, je
travail


donc en long double.
Je calcule la dérivé d'une fonction en un point grace a une methode
simple


(f(x+h)-f(x-h))/2h) mais voila,
pour 80% des cas tout va bien; et parfois, je me retrouvais avec 0,
alors


que la reponse du calcul fait sous Maple donnais un résultat.
J'ai épuré mon code autour de l'erreur jusqu'a avoir le code suivant.

long double h = 0.00000000000000000000001;
long double a = 10132.2;
if(a == a + h) cout<<"ERREUR DE CALCUL."<<endl;

et la!!!! c'est le drame!!!!

en effet a==a+h pourquoi?


Pour garantir que a+h > a il faut que h/a soit supérieur à
LDBL_EPSILON.



Je ne pense pas pourtant arriver a la limite de précision du long
double....



Chez moi LDBL_EPSILON vaut 1E-19 et ton h/a vaut environ 1E-27.

Le problème général est que dans un calcul numérique avec des
flottants le quotient (f(a+h)-f(a-h))/2h ne converge pas vers f'(a)
pour h->0 parce que la soustraction de deux valeurs trés proches
détruit la précision du résultat au lieu de l'augmenter.

--
Horst




Loïc Joly
Le #738373
Alexandre wrote:
"Cédric BILLOT" news:c4hd61$sip$

long double h = 0.00000000000000000000001;
long double a = 10132.2;
if(a == a + h) cout<<"ERREUR DE CALCUL."<<endl;
et la!!!! c'est le drame!!!!
en effet a==a+h pourquoi?
Je ne pense pas pourtant arriver a la limite de précision du long



double....



Non, peut-être pas, mais en tout cas la constante est de type double,
elle.... Donc nulle.... Il faut ajouter un suffixe LD



Cette constante h peut être définie différente de 0 en double, même un
float serait suffisant. On est en virgule flottante, donc il n'y a aucun
problème avec h qui vaut 1e-23. Seul a+h pose problème.

--
Loïc




Publicité
Poster une réponse
Anonyme