Précédent   Forum du club des développeurs et IT Pro > C et C++ > C > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, FAQ, sources, et autres ressources pour la rubrique C.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 09/12/2009, 15h11   #1
huit_six
Membre confirmé
 
Inscription : avril 2009
Messages : 180
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 180
Points : 219
Points : 219
Par défaut Faites attention aux floats !

Code :
1
2
3
4
5
6
7
8
9
#include <stdlib.h>
#include <stdio.h>
 
int main (int argc, char *argv[]) {
	float f = 23413470 + 1;
	printf("%f\n", f);
 
	return EXIT_SUCCESS;
}
sortie console :
C'est certainement machine dépendant, même certainement dépendant du compilo, mais franchement ça fout les boules quand ça arrive .
(gcc 4.4.1 ubuntu 9.10 32bits)
huit_six est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2009, 16h31   #2
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 431
Détails du profil
Informations personnelles :
Nom : Homme Patrick Gonord
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Enseignement

Informations forums :
Inscription : juin 2005
Messages : 5 431
Points : 12 923
Points : 12 923
C'est normal ! Ca dépend de la représentation des floats.
Classiquement, tu as certainement une mantisse sur 23 bits pour ton float (de 4 octets).
Au delà de 2^^24 (16.777.216) (24 parce que 1 bit est implicite) certaines valeurs entières deviennent approchées puisque devant être codées sur plus de 23 bits et tu n'auras plus au fur et à mesure que tu augmentes le nombre que des valeurs multiples de 2 puis de 4 etc.
__________________
Publication : Concepts en C

Mon avatar : Glenn Gould

--------------------------------------------------------------------------
Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
diogene est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2009, 17h38   #3
huit_six
Membre confirmé
 
Inscription : avril 2009
Messages : 180
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 180
Points : 219
Points : 219
Je suis d'accord, mais je postais ce message pour bien mettre l'accent sur les dangers de la représentation des réels en C. Ce genre de bug (que je viens d'avoir cette après midi) est difficile à déboguer : je croyais que c'était un pointeur foireux, dépassant d'un tableau qui me modifiait de manière bizarre mes variables !
Donc ce message c'était juste pour dire de faire attention sachant que souvent il est possible d'utiliser des ints en remplacement...
huit_six est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2009, 17h47   #4
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 431
Détails du profil
Informations personnelles :
Nom : Homme Patrick Gonord
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Enseignement

Informations forums :
Inscription : juin 2005
Messages : 5 431
Points : 12 923
Points : 12 923
L'erreur est d'utiliser des floats pour représenter des entiers si la nature de la valeur est d'être entière.
__________________
Publication : Concepts en C

Mon avatar : Glenn Gould

--------------------------------------------------------------------------
Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
diogene est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/12/2009, 19h36   #5
fearyourself
Rédacteur/Modérateur
 
Avatar de fearyourself
 
Homme
Ingénieur Informaticien Senior
Inscription : décembre 2005
Messages : 5 001
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 32
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Ingénieur Informaticien Senior
Secteur : Industrie

Informations forums :
Inscription : décembre 2005
Messages : 5 001
Points : 10 736
Points : 10 736
Citation:
Envoyé par diogene Voir le message
L'erreur est d'utiliser des floats pour représenter des entiers si la nature de la valeur est d'être entière.
En effet. L'utilisation de double aura bien sûr le même souci mais pas pour les mêmes valeurs, pour le voir, faudra avoir des valeurs beaucoup plus grandes.

Citation:
23413471.000000
Jc
fearyourself est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2009, 10h44   #6
huit_six
Membre confirmé
 
Inscription : avril 2009
Messages : 180
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 180
Points : 219
Points : 219
En fait plus concrètement, le programme dans lequel j'utilisais des réels calculait le nombre (décimal) puis plaçais la virgule en divisant par une puissance de dix...
Citation:
L'erreur est d'utiliser des floats pour représenter des entiers si la nature de la valeur est d'être entière.
Je suis parfaitement d'accord, mais j'irai plus loin en disant qu'il vaut mieux, si possible, utiliser des entiers quand on a affaire à des décimaux, car il n'y a pas de surprise, on peut savoir exactement quand arrivent les dépassements de capacité.
huit_six est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2009, 22h48   #7
PRomu@ld
Responsable Algorithmes
 
Avatar de PRomu@ld
 
Homme Romuald Perrot
Attaché Temporaire d'Enseignement et de Recherche (ATER)
Inscription : avril 2005
Messages : 4 146
Détails du profil
Informations personnelles :
Nom : Homme Romuald Perrot
Âge : 27
Localisation : France

Informations professionnelles :
Activité : Attaché Temporaire d'Enseignement et de Recherche (ATER)
Secteur : Enseignement

Informations forums :
Inscription : avril 2005
Messages : 4 146
Points : 6 166
Points : 6 166
Plusieurs solutions sont envisageables :

-> Utiliser une bibliothèque de précision arbitraire (mais le calcul n'est pas exact)
-> Utiliser des rationnels (même si tout n'est pas représentable), ça permet de faire des calculs exacts, reste les problèmes mémoire. Mais suivant l'application ça peut passer.
__________________
http://rperrot.developpez.com
http://phos-graphein.fr

Vous désirez contribuer à la rubrique algorithmique, n'hésitez pas à me contacter.
PRomu@ld est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/12/2009, 09h45   #8
souviron34
Expert Confirmé Sénior
 
Inscription : janvier 2007
Messages : 9 569
Détails du profil
Informations personnelles :
Âge : 55

Informations forums :
Inscription : janvier 2007
Messages : 9 569
Points : 11 849
Points : 11 849
ceci devrait te donner une réponse (pratiquement) correcte :

Code :
	float f = 23413470.0f + 1.0f;
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

Consultant indépendant.
Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
C, Fortran, XWindow/Motif, Java

Je ne réponds pas aux MP techniques
souviron34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/12/2009, 10h25   #9
Pouet_forever
Membre chevronné
 
Avatar de Pouet_forever
 
Inscription : octobre 2009
Messages : 671
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 671
Points : 724
Points : 724
Chez moi ça donne toujours 23413472.000000 :'(
__________________
Plus tu pédales moins fort, moins t'avances plus vite.
Pouet_forever est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/12/2009, 11h00   #10
Lavock
Membre expérimenté
 
Avatar de Lavock
 
Inscription : octobre 2009
Messages : 560
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 560
Points : 543
Points : 543
Les float ont un précision de 6 digit. D'ou l'erreur. Il n'est simplement pas possible d'écrire se nombre à l'aide de ceux-ci.

D'ailleurs, l'opération (première) additionne d'abord deux long, ce qui te donne un long (valeur exacte donc). Ensuite, celui-ci est transformer du mieux qu'il peux en float.

Le problème est que le C travail toujours avec IEEE754 1985, réviser en 1987. En même temps, la dernière norme est sortie l'an dernier, et accueil, chaleureusement, les décimales (32/64/128). Est-ce que le C les verras se rajouter à une norme C1x ? J'espère quand même >< !
Lavock est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 16h36.


 
 
 
 
Partenaires

Hébergement Web