[C] 10 * 0.334 = 3.33999

10 * 0.334 = 3.33999 [C] - C++ - Programmation

Marsh Posté le 12-02-2003 à 11:46:57    

Voici mon code :
 

Code :
  1. int iPow=10;
  2. float fPout=0.334;
  3. for(int i=0;i<iPow;i++) {
  4.  printf("Pout = %f\n",fPout);
  5.  printf("Pout*10 = %f\n",fPout*10);
  6.  pout*=10;
  7. }


 
Donc je multiplie 3 fois mon float par 10.
Je m'attendais à avoir comme résultat :
0.334
3.34
33.4
334
 
Mais voici ce que j'obtiens :
 
thor:/home/linux/Documents # ./essai
Pout = 0.334000
Pout*10 = 3.340000
Pout = 3.340000
Pout*10 = 33.399999
Pout = 33.399998
Pout*10 = 333.999977
 
 
Lors de la seconde multiplication, 3.34*10 donne 33.399999
 
 
J'utilise Linux SuSE 8.1,
compilateur gcc-3.2-39


Message édité par warp le 12-02-2003 à 11:49:19

---------------
Il n'est pas nécéssaire de réussir pour persévérer.
Reply

Marsh Posté le 12-02-2003 à 11:46:57   

Reply

Marsh Posté le 12-02-2003 à 12:00:38    

Second test sur une autre machine :
 
résultat pareil : SuSE 6.4
gcc-2.95.2-26


---------------
Il n'est pas nécéssaire de réussir pour persévérer.
Reply

Marsh Posté le 12-02-2003 à 12:09:40    

IL faut mieux que tu declares fPout en double tu auras une meilleur précision.

Reply

Marsh Posté le 12-02-2003 à 12:10:09    

Et avec un double, çà fait quoi ?


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 12-02-2003 à 12:14:14    


 
Bah quoi, c'est le comportement normal des flotant (qu'il faut toujours manipuler avec un intervale d'incertitude à cause de leur structure interne).


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 12-02-2003 à 12:45:21    

Problème résulu en fixant la précision : %.2f par exemple.
 
De plus cela fonctionne effectivement avec un double.


---------------
Il n'est pas nécéssaire de réussir pour persévérer.
Reply

Marsh Posté le 12-02-2003 à 13:15:41    

Y en a qui "proposent" de "préciser" le type en mettant un point, genre 10.0f pour flottant, 10.0 pour double (ou 10. je sais plus, 10 serait int par défaut), comme ça, il n'y a plus de doute (mais résoudrait-ce le problème ?).

Reply

Marsh Posté le 12-02-2003 à 14:52:53    

warp a écrit :

Voici mon code :
 

Code :
  1. int iPow=10;
  2. float fPout=0.334;
  3. for(int i=0;i<iPow;i++) {
  4.  printf("Pout = %f\n",fPout);
  5.  printf("Pout*10 = %f\n",fPout*10);
  6.  pout*=10;
  7. }


 
Donc je multiplie 3 fois mon float par 10.
Je m'attendais à avoir comme résultat :
0.334
3.34
33.4
334
 
Mais voici ce que j'obtiens :
 
thor:/home/linux/Documents # ./essai
Pout = 0.334000
Pout*10 = 3.340000
Pout = 3.340000
Pout*10 = 33.399999
Pout = 33.399998
Pout*10 = 333.999977
 
 
Lors de la seconde multiplication, 3.34*10 donne 33.399999
 
 
J'utilise Linux SuSE 8.1,
compilateur gcc-3.2-39


 
Je vais prescrire attention .........
..........
Golberg  
"What Every Computer Scientist Should Know About Floating Point Arithmetic"
http://citeseer.nj.nec.com/goldberg91what.html
 
version HTML sur le site de sun :
http://docs.sun.com/source/806-3568/ncg_goldberg.html
 
p'tain c'est vieux en fait, c'est marrant que les profs ne le font toujours pas lire à leur élèves !

Reply

Marsh Posté le 12-02-2003 à 15:36:25    

CARBON_14 a écrit :

Y en a qui "proposent" de "préciser" le type en mettant un point, genre 10.0f pour flottant, 10.0 pour double (ou 10. je sais plus, 10 serait int par défaut), comme ça, il n'y a plus de doute (mais résoudrait-ce le problème ?).


L'arithmétique sur nombres à virgule flottante n'est PAS une arithmétique exacte. Apprenez-le et rabâchez-le.
Et spécifier une précision d'affichage, ça s'appelle "placer une feuille de vigne sur l'immondice". L'immondice est toujours là, mais on ne la voit plus (tant qu'elle ne grossit pas trop...)
 
"Cachez ce sein que je ne saurais voir", écrivait Molière...   :sarcastic:


Message édité par BifaceMcLeOD le 12-02-2003 à 15:36:47
Reply

Marsh Posté le 12-02-2003 à 16:00:00    

BifaceMcLeOD a écrit :


L'arithmétique sur nombres à virgule flottante n'est PAS une arithmétique exacte. Apprenez-le et rabâchez-le.
Et spécifier une précision d'affichage, ça s'appelle "placer une feuille de vigne sur l'immondice". L'immondice est toujours là, mais on ne la voit plus (tant qu'elle ne grossit pas trop...)
 
"Cachez ce sein que je ne saurais voir", écrivait Molière...   :sarcastic:


 
Evidemment adaptee a la situation, en particulier si le resultat attendu a un ordre de grandeur connu, ca evite les mauvaises surprises dans tous les sens. Mettre une feuille de vigne sur l'immondice n'empeche pas de marcher dessus.
 
Sinon :jap: a tout le reste.


Message édité par Angel_Dooglas le 12-02-2003 à 16:00:52
Reply

Marsh Posté le 12-02-2003 à 16:00:00   

Reply

Marsh Posté le 13-02-2003 à 13:56:00    

de toute facon on prouve en maths que  
.99999999999..... = 1 (exactement)
 
donc en simple precision (6 chiffres significatifs au plus)
33.399999 = 33.4 (le '=' signifiant que les 2 nombres sont identiques vue le systeme de representation des nombres)
 
rien de bizarre là dedans !

Reply

Marsh Posté le 13-02-2003 à 17:54:56    

Si Cow, comme l'est la séquence suivante :
 
a = 1
b = a + 10^20
c = b - 10^20
 --> ce qui donne... c = 0.
 
Ce n'est pas du tout logique, et pour un néophyte, c'est très bizarre parce que c'est totalement contre-intuitif. Mais cela fait partie de l'apprentissage que d'admettre que les nombres à virgule flottante fonctionnent comme cela sur un ordinateur.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed