Problème avec la représentation des points flottants

Essayez le code suivant:

#include  unsigned char TEST_COMPILER_AS13 = 1.18 * 100; int main(void) { printf("%d" , TEST_COMPILER_AS13); // your code goes here return 0; } 

en utilisant C https://www.codechef.com/ide

le résultat serait 117

si nous remplacions 1.18 par 1.17, le résultat serait 116, mais si nous utilisions 1.19,1.20,1.15, etc., le résultat serait correct 119, 120, 115.

en utilisant un compilateur en ligne différent, dites: http://codepad.org/, les résultats pour 1.18 et 1.17 seraient bien, mais si vous essayiez les versions 1.13, 1.14, 1.15, les résultats seraient respectivement 112, 113, 114

Je me frotte la tête et je ne comprends pas pourquoi cela se produit. Note: J’ai essayé différents compilateurs DIAB, COSMIC, MinGw .. etc ont tous le même problème. alors qu’est-ce qui manque ici ou comment les opérations en virgule flottante sont effectuées.

Remarque: pour résoudre ce problème, vous pouvez simplement lancer l’opération avec float afin que la déclaration soit la suivante

 unsigned char TEST_COMPILER_AS13 = (float) (1.18 * 100); 

Je suis ouvert à vos réponses, je veux vraiment comprendre comment cela fonctionne. pourquoi cela fonctionne pour un certain nombre et d’autres non. Pourquoi le compilateur diffère-t-il sur la façon de le gérer, existe-t-il des options de compilateur qui pourraient affecter le comportement du compilateur

Dans l’état actuel des choses, la valeur en virgule flottante est tronquée en un type entier (caractère non signé). Pour arrondir au plus proche, utilisez ceci à la place.

 unsigned char TEST_COMPILER_AS13 = 1.18 * 100 + 0.5; 

Bien que cela puisse le “réparer” dans ce cas particulier, il y aura toujours des problèmes de précision avec les calculs en virgule flottante. Voir le lien posté par @JohnnyMopp dans un commentaire.


[EDIT] Pour voir ce qu’un compilateur “pense” de 1,18 * 100, vous pouvez l’imprimer avec la plus grande précision (au plus 17 chiffres décimaux significatifs dans le cas du double ).

 printf("%.16f * 100 = %.16f\n", 1.18, 1.18 * 100);