Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
4045 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  incompréhension du fonctionnemnent des nombres flottants

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

incompréhension du fonctionnemnent des nombres flottants

n°531867
iS@mi
Resistance is futile !
Posté le 05-10-2003 à 15:53:00  profilanswer
 

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.
 

Code :
  1. if((dSolde - RepasRecord->r_Prix) == .0)
  2. dSolde = .0;
  3. else
  4. dSolde -= RepasRecord->r_Prix;


 
Des idées ?
 
Edit: tout compte fait, l'astuce ne fonctionne pas  :cry:


Message édité par iS@mi le 05-10-2003 à 15:57:21
mood
Publicité
Posté le 05-10-2003 à 15:53:00  profilanswer
 

n°531873
Enidan
Posté le 05-10-2003 à 16:13:41  profilanswer
 

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

n°531879
skeye
Posté le 05-10-2003 à 16:21:58  profilanswer
 

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.
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


 :heink:  
Depuis quand des flottants ne peuvent pas être égaux?


---------------
Can't buy what I want because it's free -
n°531883
Taz
bisounours-codeur
Posté le 05-10-2003 à 16:26:45  profilanswer
 
n°531884
iS@mi
Resistance is futile !
Posté le 05-10-2003 à 16:28:32  profilanswer
 

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.
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


 
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 ?
 
 

n°531885
Taz
bisounours-codeur
Posté le 05-10-2003 à 16:29:24  profilanswer
 

c'est ça

n°531886
Taz
bisounours-codeur
Posté le 05-10-2003 à 16:29:39  profilanswer
 

enfin pas vraiment un problème de précision

n°531888
skeye
Posté le 05-10-2003 à 16:31:20  profilanswer
 


lu, compris et je m'auto-flagelle...mais c'est quand même très moche! :pt1cable:


---------------
Can't buy what I want because it's free -
n°531910
iS@mi
Resistance is futile !
Posté le 05-10-2003 à 17:39:11  profilanswer
 

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  :lol:
 
Edit: je pense avoir trouvé la solution ici :
http://msdn.microsoft.com/library/ [...] cision.asp
Je vous tiens au courant.


Message édité par iS@mi le 05-10-2003 à 17:43:04
n°531913
chrisbk
-
Posté le 05-10-2003 à 17:41:25  profilanswer
 

?
 
if (fabs(a-b)<EPSILON)
{
...
}
 
 
pis tu te debrouilles trouver l'epsilon qui te convient
 
 

mood
Publicité
Posté le 05-10-2003 à 17:41:25  profilanswer
 

n°531916
iS@mi
Resistance is futile !
Posté le 05-10-2003 à 17:47:38  profilanswer
 

Voilà, ca marche (qu'est ce qu'on deviendrait sans MSDN).
 
 

Code :
  1. #define EPSILON 0.0001   // Define your own tolerance
  2. #define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
  3. if (FLOAT_EQ((dSolde - RepasRecord->r_Prix), 0.0000))
  4.    dSolde  = .0;

n°531917
Tetedeienc​h
Head Of God
Posté le 05-10-2003 à 17:47:59  profilanswer
 

grilled :/


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°531921
bjone
Insert booze to continue
Posté le 05-10-2003 à 17:55:02  profilanswer
 

la solution de chrisbk est plus économique en principe (le fabs est simple alors qu'une comparaison en plus est coûteuse)

n°531924
Tetedeienc​h
Head Of God
Posté le 05-10-2003 à 17:58:30  profilanswer
 

d'ailleurs, pour un flottant, le fabs c'est pas un bit a changer uniquement ?


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°531931
chrisbk
-
Posté le 05-10-2003 à 18:04:45  profilanswer
 

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
 
([:ciler])

n°531932
Taz
bisounours-codeur
Posté le 05-10-2003 à 18:05:11  profilanswer
 

personne pour faire une jolie classe autour de tout ça ?

n°531943
Tetedeienc​h
Head Of God
Posté le 05-10-2003 à 18:15:36  profilanswer
 

Euh non, on me descendrait ma classe car "elle est pas Taz-compliant" :D
 
nan je deconne, je suis une bite monstrueuse en C++, je bidouille de facon laide, c'est tout.


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°531946
Taz
bisounours-codeur
Posté le 05-10-2003 à 18:27:02  profilanswer
 

Code :
  1. const long double EPSILON=0.0001;
  2. template<typename T>
  3. inline bool Equal(const T &a, const T &b)
  4. {
  5. return ((a - EPSILON) < b) && (b <( a + EPSILON));
  6. }


 
ou alors on pousse avec mieux
 
 

Code :
  1. template<typename T>
  2. struct Equal
  3. {
  4. const T Epsilon;
  5. explicit Equal(const T &e) : Epsilon(e) {}
  6. bool operator()(const T &a, const T &b) const
  7. {
  8.    return ((a - Epsilon) < b) && (b <( a + Epsilon));
  9. }
  10. };


 
 
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


Message édité par Taz le 05-10-2003 à 18:51:28
n°531961
Tetedeienc​h
Head Of God
Posté le 05-10-2003 à 18:59:51  profilanswer
 

:o
 
Je savais pas qu'il pouvait y avir des soucis avec fabs :o


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°531967
Taz
bisounours-codeur
Posté le 05-10-2003 à 19:05:18  profilanswer
 

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

n°531968
Tetedeienc​h
Head Of God
Posté le 05-10-2003 à 19:07:55  profilanswer
 

?
 
Ben ou ca l'problème :??: ( désolé d'être boulay )


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°531970
Taz
bisounours-codeur
Posté le 05-10-2003 à 19:08:37  profilanswer
 

avec les long double on est foutu.

n°531975
Tetedeienc​h
Head Of God
Posté le 05-10-2003 à 19:11:58  profilanswer
 

ah vi bien vu :o


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°531978
iS@mi
Resistance is futile !
Posté le 05-10-2003 à 19:34:00  profilanswer
 

Sinon que veux dire EPSILON ?
 
Je n'en ai jamais entendu parler (ca fait base spacial startrek  :D).
 

n°531980
chrisbk
-
Posté le 05-10-2003 à 19:40:47  profilanswer
 

bah rien c une lettre grecque
generalement on s'en sert pour decrire une petite valeur

n°531985
Taz
bisounours-codeur
Posté le 05-10-2003 à 20:02:46  profilanswer
 

par ce que c'est la plus petite &#949;
 
bug  :o


Message édité par Taz le 05-10-2003 à 20:03:44
n°531986
skeye
Posté le 05-10-2003 à 20:04:49  profilanswer
 

iS@mi a écrit :

Voilà, ca marche (qu'est ce qu'on deviendrait sans MSDN).
 
 

Code :
  1. #define EPSILON 0.0001   // Define your own tolerance
  2. #define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
  3. if (FLOAT_EQ((dSolde - RepasRecord->r_Prix), 0.0000))
  4.    dSolde  = .0;




Surement grillé par la suite, mais euh

Code :
  1. FLOAT_EQ((dSolde - RepasRecord->r_Prix), 0.0000)


 
serait quand même mieux en  

Code :
  1. FLOAT_EQ(dSolde, RepasRecord->r_Prix)


non?


Message édité par skeye le 05-10-2003 à 20:05:05

---------------
Can't buy what I want because it's free -
n°531989
Taz
bisounours-codeur
Posté le 05-10-2003 à 20:14:41  profilanswer
 

les macros ça pue, je suis à deux doigts de censurer :o

n°531990
skeye
Posté le 05-10-2003 à 20:18:55  profilanswer
 

Taz a écrit :

les macros ça pue, je suis à deux doigts de censurer :o


Ce serait de l'abus de pouvoir! :o


---------------
Can't buy what I want because it's free -
n°531991
Taz
bisounours-codeur
Posté le 05-10-2003 à 20:19:57  profilanswer
 

skeye a écrit :


Ce serait de l'abus de pouvoir! :o

modofacho  :o

n°531993
skeye
Posté le 05-10-2003 à 20:20:57  profilanswer
 

Taz a écrit :

modofacho  :o  


Te prends pas pour Harko hein!:o
...et on dévie du sujet là! :o


---------------
Can't buy what I want because it's free -
n°531994
iS@mi
Resistance is futile !
Posté le 05-10-2003 à 20:23:46  profilanswer
 

skeye a écrit :


Surement grillé par la suite, mais euh

Code :
  1. FLOAT_EQ((dSolde - RepasRecord->r_Prix), 0.0000)


 
serait quand même mieux en  

Code :
  1. FLOAT_EQ(dSolde, RepasRecord->r_Prix)


non?


 
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  :D  
J'utilise que des templates inline.


Message édité par iS@mi le 05-10-2003 à 20:24:49
n°531995
chrisbk
-
Posté le 05-10-2003 à 20:24:32  profilanswer
 

>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


Message édité par chrisbk le 05-10-2003 à 20:26:25
n°531999
iS@mi
Resistance is futile !
Posté le 05-10-2003 à 20:28:55  profilanswer
 

chrisbk a écrit :

>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é  


 
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;


Message édité par iS@mi le 05-10-2003 à 20:31:08
n°532001
chrisbk
-
Posté le 05-10-2003 à 20:30:57  profilanswer
 

[:humanrage]

n°532007
iS@mi
Resistance is futile !
Posté le 05-10-2003 à 20:35:22  profilanswer
 


 
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 :
  1. if((solde-PrixRepas) == 0.0)
  2.   solde = 0.0; // L'astuce pour éviter d'avoir-2.2204460492503131e-016  
  3. else
  4.   solde -= PrixRepas; // rien à signaler, on soustrait normalement


Message édité par iS@mi le 05-10-2003 à 20:37:09
n°532010
chrisbk
-
Posté le 05-10-2003 à 20:37:08  profilanswer
 

merci j'avais compris :D
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

n°532012
chrisbk
-
Posté le 05-10-2003 à 20:39:38  profilanswer
 

note finalement, en virgule fixe t'aurais pas eu tous ces problemes [:meganne]

n°532013
iS@mi
Resistance is futile !
Posté le 05-10-2003 à 20:40:18  profilanswer
 

chrisbk a écrit :

merci j'avais compris :D
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


 
Ha zuste  :lol:  :)  
C'est vrai, que c'est mieux aussi, toutes mes zescuses.

n°532014
Taz
bisounours-codeur
Posté le 05-10-2003 à 20:41:55  profilanswer
 

faisez bien attention que
 

Code :
  1. float a;
  2. // ...
  3. a==0.0;
  4. a==0.0f;


 
sont deux choses différentes

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  incompréhension du fonctionnemnent des nombres flottants

 

Sujets relatifs
[HTML] Format des nombres dans un input[VB] Question sur la facon de VB de procéder avec les nombres
Surnaturel => conversion de nombres Access/VBA, incompréhensible !!!Comment obtenir des nombres aléatoires mais seulement des entiers ?
[PHP] Nombres de réponses d'une query[VBA excel] rouddown et nombres décimaux
[C] gestion des nombres aléatoiresPGCD de plus de 2 nombres
modification du format des nombres[php] valeur comprise entre deux nombres
Plus de sujets relatifs à : incompréhension du fonctionnemnent des nombres flottants


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)