Cast de double en long et vice-versa : question pas si triviale

Résolu
BenGourion73 Messages postés 9 Date d'inscription mardi 19 décembre 2000 Statut Membre Dernière intervention 2 mars 2009 - 1 sept. 2008 à 09:46
Stanel Messages postés 6 Date d'inscription vendredi 18 mai 2007 Statut Membre Dernière intervention 16 décembre 2008 - 5 sept. 2008 à 15:42
Bonjour,

Ma question est très simple. je souhaite gérer des nombres entiers mais avec le type double. Le hic, c'est que C++ a une facheuse tendance à parfois transformer 14.0 en 13.9999999999999. Or typiquement, cela compromet un test d'égalité avec un long même si celui-ci est casté en double... Ma solution actuel est de fixer un static const ECARTLNG qui vaut 1.10-16
et quand je teste un double à l'égalité avec long casté en double, je teste l'écart.

En code, ça donne ça :

double Toto = 13.9999999999999999  /// Au départ, Toto a été initialisé à 14.0 mais à un moment donné 14.0 est 
                                                                /// devenu 13.9999999999999999
long Bob = 14;

if (Toto = = (double)Bob) /// la clairement, ça va donner false alors que je souhaite true !
   return true;
else 
   return false

//// Ma solution  
const static double ECARTLNG 1e-16
if (Toto-(double)Bob > ECARTLNG)
   return false;
else
   return true;

là a priori, le test d'égalité va fonctionner mais n'y a t'il pas moyen de faire autrement  ?

Série d'instructions sur Toto

2 réponses

BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 103
1 sept. 2008 à 11:55
Hello,
Il n'est pas conseillé de faire des tests d'égalité sur les flottants, justement à cause des arrondis dues à la précision machine.
Généralement, on teste si la différence entre les 2 valeurs est inférieures (en valeur absolue) à un certain epsilon:

if (fabs(x2 - x1)<epsilon)
  // on peut dire que les 2 valeurs sont égales
else
  // on peut dire que les 2 valeurs sont différentes

Donc ta solution est tout à fait valable.

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
3
Stanel Messages postés 6 Date d'inscription vendredi 18 mai 2007 Statut Membre Dernière intervention 16 décembre 2008
5 sept. 2008 à 15:42
Pour obtenir en "double" des entiers, il faut que les resultats soit ajustes avec les
functions floor (pour les valeurs > 0) ou ceil ( < 0). Exemple:

double a,b;

a=123456e0;
b=floor(sqrt(a)+0.5);
 
0
Rejoignez-nous