incompréhension du fonctionnemnent des nombres flottants - C++ - Programmation
Marsh Posté le 05-10-2003 à 16:13:41
Il ne faut jamais faire de tests d'égalité avec des nombres flottants car tu as toujours un pb de précision.
A la place, il faut que tu fasse une comparaison du genre :
if ( (a - b) < 1.0e-16 )
c'est-à-dire que tu spécifie la marge d'erreur que tu acceptes
Marsh Posté le 05-10-2003 à 16:21:58
Enidan a écrit : Il ne faut jamais faire de tests d'égalité avec des nombres flottants car tu as toujours un pb de précision. |
Depuis quand des flottants ne peuvent pas être égaux?
Marsh Posté le 05-10-2003 à 16:26:45
http://forum.hardware.fr/forum2.ph [...] 339&cat=10
http://www.isty-info.uvsq.fr/~rume [...] c0011.html
Marsh Posté le 05-10-2003 à 16:28:32
Enidan a écrit : Il ne faut jamais faire de tests d'égalité avec des nombres flottants car tu as toujours un pb de précision. |
J'imagine que mon problème est dû à la précision de mes nombres flotants ?
En fait il ne fait pas (3.25-3.25)
mais (3.249999999999... - 3.249999999999...), ce qui donne un truc 0.0000000000000000000000000000000000000000000000....1
Le double n'étant pas assez précis, il me retourne 2.2204460492503131e-016 ?
Marsh Posté le 05-10-2003 à 16:31:20
Taz a écrit : http://forum.hardware.fr/forum2.ph [...] 339&cat=10 |
lu, compris et je m'auto-flagelle...mais c'est quand même très moche!
Marsh Posté le 05-10-2003 à 17:39:11
J'ai crié victoire trop tôt:
Voilà, le problème est que ma soustraction peut également donner comme résultat un nombre négatif et que dans le cas de if ( (a - b) < 1.0e-16 ) tous mes nombres négatifs seront définis à zéro ce qui n'est pas acceptable pour mon programme.
Je travaille avec des Euro, donc la précision serait de l'ordre des centièmes.
J'utilise ceci en attendant mais c'est à mon avis pas conseillé :
if ( (a - b) == -2.2204460492503131e-016 )
J'ai également essayé if(((a - b) < 0.999) && ((a - b) > -0.999) mais comme le résultat de ma soustraction est -2.2204460492503131e-016 ca ne fonctionne pas.
Auriez-vous une astuce fiable pour savoir si le résultat de ma soustration est égual à zéro tip top ?
PS: Note, je peux aussi tout convertir en char* et définir ma valeur comme étant zéro si mon string est égual à "-0.00" mais bon c'est vachement bricoleur du dimanche ca
Edit: je pense avoir trouvé la solution ici :
http://msdn.microsoft.com/library/ [...] cision.asp
Je vous tiens au courant.
Marsh Posté le 05-10-2003 à 17:41:25
?
if (fabs(a-b)<EPSILON)
{
...
}
pis tu te debrouilles trouver l'epsilon qui te convient
Marsh Posté le 05-10-2003 à 17:47:38
Voilà, ca marche (qu'est ce qu'on deviendrait sans MSDN).
Code :
|
Marsh Posté le 05-10-2003 à 17:47:59
grilled
Marsh Posté le 05-10-2003 à 17:55:02
la solution de chrisbk est plus économique en principe (le fabs est simple alors qu'une comparaison en plus est coûteuse)
Marsh Posté le 05-10-2003 à 17:58:30
d'ailleurs, pour un flottant, le fabs c'est pas un bit a changer uniquement ?
Marsh Posté le 05-10-2003 à 18:04:45
tetedeiench a écrit : d'ailleurs, pour un flottant, le fabs c'est pas un bit a changer uniquement ? |
ben si
float roger = -1;
(*((DWORD *)&roger)) & 7FFFFFFF
()
Marsh Posté le 05-10-2003 à 18:15:36
Euh non, on me descendrait ma classe car "elle est pas Taz-compliant"
nan je deconne, je suis une bite monstrueuse en C++, je bidouille de facon laide, c'est tout.
Marsh Posté le 05-10-2003 à 18:27:02
Code :
|
ou alors on pousse avec mieux
Code :
|
edit je suis bête
j'avais écris initialement
/* ou la version avec fabs, gaffe, assurez vous d'avoir une fonction qui utilise le bon type fabs fonctionne avec les double
rendez vous avec <tgmath.h> du C99 pour en savoir plus (le C++ planche dessus) */
mais Recherche En Cours
Marsh Posté le 05-10-2003 à 18:59:51
Je savais pas qu'il pouvait y avir des soucis avec fabs
Marsh Posté le 05-10-2003 à 19:05:18
plus de précision bientot
en C++, C89
double fabs(double)
int abs(int)
long int labs(long int);
d'ou le problème dans notre cas
Marsh Posté le 05-10-2003 à 19:07:55
?
Ben ou ca l'problème ( désolé d'être boulay )
Marsh Posté le 05-10-2003 à 19:11:58
ah vi bien vu
Marsh Posté le 05-10-2003 à 19:34:00
Sinon que veux dire EPSILON ?
Je n'en ai jamais entendu parler (ca fait base spacial startrek ).
Marsh Posté le 05-10-2003 à 19:40:47
bah rien c une lettre grecque
generalement on s'en sert pour decrire une petite valeur
Marsh Posté le 05-10-2003 à 20:02:46
par ce que c'est la plus petite ε
bug
Marsh Posté le 05-10-2003 à 20:04:49
iS@mi a écrit : Voilà, ca marche (qu'est ce qu'on deviendrait sans MSDN).
|
Surement grillé par la suite, mais euh
Code :
|
serait quand même mieux en
Code :
|
non?
Marsh Posté le 05-10-2003 à 20:18:55
Taz a écrit : les macros ça pue, je suis à deux doigts de censurer |
Ce serait de l'abus de pouvoir!
Marsh Posté le 05-10-2003 à 20:19:57
ReplyMarsh Posté le 05-10-2003 à 20:20:57
Taz a écrit : modofacho |
Te prends pas pour Harko hein!
...et on dévie du sujet là!
Marsh Posté le 05-10-2003 à 20:23:46
skeye a écrit :
|
Non, je vérifie juste si le résultat de la soustraction (dSolde - RepasRecord) est égale à zéro.
Si oui, je dis que dSolde est = 0.0 dans ces cas là.
Sinon Taz, pas ma faute si Microsoft met des Macro pour leur fonctions
J'utilise que des templates inline.
Marsh Posté le 05-10-2003 à 20:24:32
>Non, je vérifie juste si le résultat de la soustraction (dSolde - >RepasRecord) est égual à zéro.
>Si oui, je dis que dSolde est = .0 dans ces cas là.
ce qui revient a tester l'egalité
edit : la reponse rapide, ou comment faire des quotes ignobles
Marsh Posté le 05-10-2003 à 20:28:55
chrisbk a écrit : >Non, je vérifie juste si le résultat de la soustraction (dSolde - >RepasRecord) est égual à zéro. |
Heu oui ???
Comme 0.2499999-0.2499999 ne me retourne pas zéro tip top mais -2.2204460492503131e-016, j'utilise la fonction Equal pour savoir si ma soustraction de mes double donne bien 0.00.
Si oui, je dis que dSolde est = 0.0.
if((a-b) == 0.0)
a = 0.0;
else
a -= b;
Marsh Posté le 05-10-2003 à 20:35:22
Tu ne vois pas ???
Si l'utilisateur de mon programme supprime un repas de la liste, je dois soustraire du solde, le prix de ce repas.
Si maintenant il s'avère que le solde est du même montant que le prix du repas, après soustraction, le solde sera à zéro mais la soustraction des double n'est pas parfaite, donc j'utilise le stratège (ex. : solde(25.10), PrixRepas(25.10), Solde-=PrixRepas = 0.00).
Code :
|
Marsh Posté le 05-10-2003 à 20:37:08
merci j'avais compris
le point important de ta phrase est :
"si maintenant il s'avère que le solde est du même montant que le prix du repas"
donc tu peux tester l'egalité au lieu de faire une soustraction et de tester sur 0, c ce que voulais dire skeye
Marsh Posté le 05-10-2003 à 20:39:38
note finalement, en virgule fixe t'aurais pas eu tous ces problemes
Marsh Posté le 05-10-2003 à 20:40:18
chrisbk a écrit : merci j'avais compris |
Ha zuste
C'est vrai, que c'est mieux aussi, toutes mes zescuses.
Marsh Posté le 05-10-2003 à 20:41:55
faisez bien attention que
Code :
|
sont deux choses différentes
Marsh Posté le 05-10-2003 à 15:53:00
Voilà,
J'ai un drôle de problème avec mes variables double :
Qd j'effectue cette opération : dSolde -= RepasRecord->r_Prix et que les deux variables double ont la même valeur, que le résultat final me donne -2.2204460492503131e-016 aulieu de 0.00.. (5-=5 = 0).
Cela ne se passe que qd les deux variables ont la même valeur et pour l'instant j'utilise une astuce mais c'est pas très beau.
Des idées ?
Edit: tout compte fait, l'astuce ne fonctionne pas
Message édité par iS@mi le 05-10-2003 à 15:57:21