Je viens de porter un vieux bout de code fait par un prestataire sur une SUN vers un PC sous w2k.
En recettant, j'ai obtenu une erreur d'arrondi étrange dans une fonction qui convertissait un montant stocké dans un chaine dans un entier(montant en centimes).
Outre le fait que la fonction etait "grouik", je ne comprenais pas
l'erreur. Je l'ai reproduite avec çà :
char montant[16];
strcpy(montant, "75.32");
i=(int )(atof(montant)*100.0);
i vaut 7531 Ă la fin. J'ai mis du temps Ă percuter. Et vous ?
Enzo
PS : Dommage, le prestataire qui m'a laissé çà est dèjà parti. Je lui aurai fait payer l'apéro.
# Pas mal.
Posté par reno . Évalué à  2.
Ah, le calcul flottant, c'est une source inepuisable d'"amusements"..
# C'est comme tout...
Posté par pasBill pasGates . Évalué à  2.
C'est ca le cote marrant de l'informatique, expliquer a tes collegues sur quelle connerie triviale tu as perdu 2 jours :+)
# Et l'homme inventa le BCD...
Posté par mac . Évalué à  2.
# heu...
Posté par bergamote23 . Évalué à  2.
ce passe Ă ceux qui n'ont pas le niveau pour comprendre d'eux mĂŞme mais qui sont tout de mĂŞme intriguer par le truc ?
Faites pas semblant, vous attendiez tous une question de ce genre pour pouvoir flatter votre Ă©go..
[^] # Re: heu...
Posté par Enzo Bricolo 🛠⚙🛠. Évalué à  2.
http://www.greatsnakes.com/Sepal/d5/d8/atof_8c.html(...)
atof appelle strtod
http://www.greatsnakes.com/Sepal/d2/d4/strtod_8c.html#a0(...)
Mais çà devrait marcher.
Je vais regarder si çà ne dépend pas de l'implémentation.
Apparement je sui spas le seul a me poser des questions.
http://mail-index.netbsd.org/port-mips/1999/02/06/0000.html(...)
A plus,
Enzo Bricolo
[^] # Re: heu...
Posté par Enzo Bricolo 🛠⚙🛠. Évalué à  1.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main (){
char montant[16];
strcpy(montant, "75.32");
fprintf(stderr, "(%s) -> (%e) -> (%d)\n",
montant,atof(montant)*100.0, (int )(atof(montant)*100.0));
exit(0);
}
$./test_atof
(75.32) -> (7.532000e+003) -> (7531)
Voir ce thread entre autre.
http://gcc.gnu.org/ml/gcc-bugs/1998-09/msg00584.html(...)
Enzo Bricolo
[^] # C'est un concours cest ca?
Posté par Olivier MARTIN . Évalué à  1.
[^] # Re: C'est un concours cest ca?
Posté par ceituna (site web personnel) . Évalué à  3.
Commençons par le début...
Un flottant, est défini (sur 32 bits) par :
1 bit de signe
8 bits pour l'exposant (codé en complément à 2)
le reste (23 bits) pour la mantisse... (comprise entre 1 et 2)
Ainsi, le nombre 8 s'Ă©crit 1.0 *2^3, soit :
(signe) + (exposant) + (mantisse)
0 + (3) + (0.0000)
soit, en binaire :
0 . 10000010 . 00000000000000000000000
Tu suis toujours ?
On prend un nombre plus difficile :
9 soit : 1,125 *2^3, soit :
(signe) + (exposant) + (mantisse)
0 + (3) + (0.1250)
soit, en binaire :
0 . 10000010 . 00100000000000000000000
Maintenant, on prend l'exemple cité :
75,32 soit 1,176875 *2^6, soit :
(signe) + (exposant) + (mantisse)
0 + (6) + (0,176875)
en binaire :
0 . 10000101 . 00101101010001111010111
Or, cela représente une valeur de
75, 31999969482422 (+ un petit quelque chose).
Le pb du programme vient du Forcage de type (cast pour les puristes), qui tronque la valeur 7531,999969482422 en 7531.
Une belle programmation aurait plutĂ´t fait un arrondi avant de forcer au type (int).
Morale : Des fois, un arrondi est plus préci qu'un calcul "exact" (message perso pour les fanas de la qualité max et de la précision max).
CQFD.
PS : merci de me corriger si j'ai dit une bétise... C'est fréquent quand il fait beau... :=/
[^] # Re: C'est un concours cest ca?
Posté par Enzo Bricolo 🛠⚙🛠. Évalué à  1.
Enzo Bricolo
[^] # Re: C'est un concours cest ca?
Posté par ceituna (site web personnel) . Évalué à  1.
75,33 est "converti" en 75,33000183105469 sur un codage 32 bits...
Donc, le "cast" te donne 7533... CQFD.
PS : pour ceux qui veulent tester des valeurs, j'ai trouvé ce lien entre-temps... :
http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html(...)
et
http://www.h-schmidt.net/FloatApplet/IEEE754.html(...)
[^] # Re: C'est un concours cest ca?
Posté par Enzo Bricolo 🛠⚙🛠. Évalué à  1.
Dans ma recette, la multiplication par 100.0 distribuait les erreurs d'arrondi sur certaines valeurs très peu fréquentes, d'ou l'impression de "bug".
Moralité, évitez l'emploi de flottant dans le calcul de montant ou pensez à arrondi les valeurs au centimes près avant affichage.
Enzo Bricolo
PS : J'ai fouillé l'ensemble des sources manipulées par le presta et j'ai retrouvé 3 fois le "cast" malencontreux ... rogntudju ...
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.