Float *10

Résolu
kaervas Messages postés 51 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 19 avril 2008 - 14 déc. 2005 à 23:58
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 - 27 déc. 2005 à 15:24
Bonsoir,
J'ai un soucis avec les floats:

int main()
{
float nb = 3.11;

nb *= 10;
printf("%f", nb);
}

cc main.c && ./a.out
31.099998

comment ce fais-ce?
J'aimerais avoir 31.1 comme resultat...

8 réponses

ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
15 déc. 2005 à 11:14
C'est parce que les float font une approximation des valeurs décimales et certaines ne sont pas représentable exactement en mémoire

En fait le 3.11 et le 31.1 ont une représentation finie en décimal mais en réprésentation binaire c'est pas le cas. Du coup les calculs sont approchés.

Exemple : en décimal, il est impossible de représenté 1/3 avec un nombre fini de chifrres, si on se contente de 4 chiffres :val 1/3> en fait en interne on aura 0.3333val val*3> on aura en interne 0.9999 en non pas 1

Avec des double au lieu de float c'est pareil mais ca se voit moins parce que la précision est meilleurs.
3
neodelphi Messages postés 442 Date d'inscription jeudi 4 avril 2002 Statut Membre Dernière intervention 11 août 2008
15 déc. 2005 à 07:00
Essaye

printf("%4f", nb);



et

nb *= 10.0f;

neodelphi
0
kortin Messages postés 65 Date d'inscription dimanche 27 juillet 2003 Statut Membre Dernière intervention 21 avril 2006
15 déc. 2005 à 14:00
Oui, moi aussi, dans mon projet, je n'ai que des double et j'ai des valeurs qui dérapent vite !

Je crois que le C++ a besoin d'un type qui permettrait de meilleurs résultats.
0
kaervas Messages postés 51 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 19 avril 2008
16 déc. 2005 à 06:40
neodelphi non ca change rien chez moi,
mais je vois le probleme a peu pres, merci ymca2003.
Les doubles ne posent pas de problemes sur cet exemple apparement.

Ce probleme que j'avais etait pour mon recodage du printf %f, quand j'utilise un float, pour recuperer le float, ca marche mais la precision foire, par contre la j'ai essayer de recuper mon float avec un double et ca ne marche plus (il me met 0.0 dans tous les cas), je me sert d'int pour afficher les nombre apres et avant la virgule, peut-etre le cast du double en int bug?
( enfin c'est un autre probleme mais j'aimerais bien finir de maudit printf d: )
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
kortin Messages postés 65 Date d'inscription dimanche 27 juillet 2003 Statut Membre Dernière intervention 21 avril 2006
16 déc. 2005 à 10:15
Tu peux utiliser l'affichage que tu veux, les nombre stockés en mémoire sont FAUX !

même si tu avais un type doubledoubledouble, il serait toujours impossible de stocker 0.3
Regarde donc comment fonctionne la stockage d'une valeur dans la mantisse et essaie avec 0.3 => impossible.

J'ai déjà essayer d'écrire une lib qui serait un type exact, mais j'ai abandonné, je n'ai pas trouvé de solution évidente.
0
kaervas Messages postés 51 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 19 avril 2008
16 déc. 2005 à 14:39
Oui mais c'etait pour faire un printf qui "aurait l'air" de bien gerer les floats, et puis meme si c'est faux, avec les doubles, tant que ca depasse pas les 6 nbres apres la virgule, ca affiche la bonne chose.
On m'a dit de passer par le binaire, bon, plus tard =)
0
neodelphi Messages postés 442 Date d'inscription jeudi 4 avril 2002 Statut Membre Dernière intervention 11 août 2008
26 déc. 2005 à 19:51
Je comprend pas pourquoi il ne pourrait pas stocker 3.11, si le
stockage se fait avec une partie entiere pour les nombres et une autre
pour la virgule, trois chiffre ça devrait passer nan ?

neodelphi
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
27 déc. 2005 à 15:24
En décimal oui, en binaire non.

0.11 ne peut pas s'exprimer en puissance de 2
0.11 : 1/16 + 1/32 + 1/64 + 1/2048 + 1/8192 + 1/131072 = 0,10999298095703125

Donc on tombe pas sur 0.11 pile poil.
0
Rejoignez-nous