Problème avec le float

Résolu/Fermé
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 - Modifié par baladur13 le 6/10/2016 à 13:31
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 - 10 oct. 2016 à 12:12
Bonjour,

Je reste perplexe sur un point de mon programme de débutant :
//Prog.c
#include <stdio.h>
int main() {
 int n=23;
 float x=456.7;
 printf("n = %d\n",n);
 printf("x = %f\n",x);
 return(0);
}


Ce programme après compilation et exécution affiche :
n = 23
x = 456.700012

Pourquoi 12 ?
Le programme devrait afficher 5 "0" à la fin pour la valeur de x.

On m'a expliqué que c'est dû à un décalage... Par exemple avec la commande double à la place de float tout marche.
Merci pour l'explication :)

EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.

4 réponses

Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 931
6 oct. 2016 à 13:40
Bonjour

un float est un nombre à virgule flottante
https://fr.wikipedia.org/wiki/Virgule_flottante

456.700012 est le nombre exact le plus proche de 456,7.
Pour t'affranchir de ces décimales, tu peux arrondir.
https://forums.commentcamarche.net/forum/affich-4623087-variable-float-en-c#1
0
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 131
6 oct. 2016 à 16:05
"456.700012 est le nombre exact le plus proche de 456,7"
Je ne comprend pas cette affirmation... : 456.700001 est encore plus proche de 456.7...
0
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 931
6 oct. 2016 à 19:19
As tu lu l'article?
0
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 131 > Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024
Modifié par CrazyGeekMan le 7/10/2016 à 20:58
Oui j'ai bien lu l'article mais je dois vous avouer que j'ai compris très peu de chose. :/
0
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 931
Modifié par KX le 7/10/2016 à 07:24
Les floats sont enregistré sur 4 bits en little endian , j'ai pris de le temps de faire un fichier binaire avec 456.7 en entrée puis de l'ouvrir avec un éditeur hexa.


9A 59 E4 43 représente 456.700012207031.
Je ne vais pas faire une capture à chaque fois, mais si je "monte d'un"
9B 59 E4 43 représente 456.700042724409
De même si je "descend d'un"
99 59 E4 43 représente 456.699981689453

9A 59 E4 43 est donc bien le float possible le plus proche de 456.7

Quand j'étais petit, la mer Morte n'était que malade.
George Burns
0
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 131
7 oct. 2016 à 20:57
En reprenant l'écriture hexadécimale suivante : 9A 59 E4 43
En base 10 ce nombre est égal à :
somme(
9*16^7
10*16^6
5*16^5
9*16^4
14*16^3
4*16^2
4*16^1
3*16^0 )
= 2 589 582 403
Pourquoi vous trouvez que c'est égal à 456.700012207031?
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
7 oct. 2016 à 21:14
9A 59 E4 43 = 2 589 582 403 si on considère des entiers où chaque bit représente une puissance de 2, or ici on parle d'un float, donc de la norme IEEE 754 comme indiqué dans l'article Wikipedia donné par Whismeril.

Il faut donc décomposer cette valeur en binaire pour en extraire, le signe S, l'exposant E et la mantisse M puis faire le calcul
(-1)^S * M * 2^(E-127)
pour en avoir un équivalent en décimal...
0
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 131
7 oct. 2016 à 21:44
2 589 582 403 base 10
= 10011010010110011110010001000011 en base 2
Et que faire après?
Je suis désolé mais c'est la première fois que j'aborde ces termes...
Pouvez vous m'aider à résoudre un exemple puis cela m'aidera à généraliser?
0
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 931
7 oct. 2016 à 21:57
En base 10 ce nombre est égal à :
somme(
9*16^7
10*16^6
5*16^5
9*16^4
14*16^3
4*16^2
4*16^1
3*16^0 )
= 2 589 582 403

déjà non, je t'ai dit plus haut que c'est en litlle endian et toi tu calcules en big endian
Sur cet autre éditeur hexa, le longint ne donne pas du tout ton résultat (le int et le word sont codés sur 2 octets)


Ensuite tu bases ton calcul sur un nombre entier non signé alors que ta question porte sur un nombre décimal, à virgule flottante et signé.


Il existe deux façons de coder en binaire un nombre décimal:
  • soit tu es en virgule fixe, n bits avant la virgule, m bits après et un bit de signe. Sur 32 bits, si on coupe la poire en deux, on a un bits de signe, 16 bits de partie entière soit +:- 131000, et 15 bits de décimales
  • soit tu utilises la virgule flottante, et là comme décrit dans l'article du peux aller de -3,4 * 10^38 à +3,4 * 10^38 en contre partie, à quelques chiffres derrière la virgule, on ne passe pas de 1 en 1, mais de epsilon en epsilon.
0
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 131
8 oct. 2016 à 16:25
Je suis pour l'instant en L1 info (je ne comprend pas les termes comme little ou big endian..).
Je pense que pour l'instant je vais laisser cela de côté car on n'a pas encore touché aux bits etc...
J'espère que tout cela sera abordé par la suite puisque c'est bien dommage de ne pas comprendre le fonctionnement des commandes :/
0
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 131
8 oct. 2016 à 16:28
Merci quand même pour avoir essayer de m'expliquer le fonctionnement des nombres à virgule flottante :)
0
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 931
Modifié par Whismeril le 8/10/2016 à 23:15
Little endian octet de poids faible à gauche. Mais bon google te l'aurait dit si tu avais pris la peine de chercher....

donc 9A 59 E4 43 est en fait 43 E4 59 9A
ce qui donne
01000011111001000101100110011010(2) =>1139038618(10) comme le montre XVI32 en longint.
Et si tu veux vérifier avec une tierce partie
http://sebastienguillon.com/test/javascript/convertisseur.html

Quand j'étais petit, la mer Morte n'était que malade.
George Burns
0
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 131
Modifié par CrazyGeekMan le 9/10/2016 à 13:01
"Little endian octet de poids faible à gauche."
Penses-tu franchement que cela m'avance en quelque chose?
Maintenant cela m'oblige de voir ce qu'est un octet de poids faible.
On est dans des termes informatiques qui impliqueront de nouveaux.
Il est plus facile de traiter cette question lorsqu'on a des bases..
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 9/10/2016 à 13:30
"Il est plus facile de traiter cette question lorsqu'on a des bases"
À toi de les acquérir ces bases → https://fr.wikipedia.org/wiki/Endianness

En gros ce que Whismeril veut dire, c'est que si tu ne lis pas les octets dans le bon ordre, ta décomposition en bits est fausse, donc tout le reste aussi.

12345 et 54321 ça n'a rien à voir... idem pour 9A59E443 et 43E4599A

Si je reprends l'impression écran de XVI32 ci dessous on voit que le fichier lit les 4 octets 9A 59 E4 43 en little indian, donc de droite à gauche, ce qui signifie que la valeur hexadécimale à lire est 0x43E4599A et c'est ce nombre qui vaut 456.7

C'est seulement si le fichier avait été lu en big indian qu'on aurait pu avoir une valeur hexadécimale correspond à 0x9A56E443 mais qui vaudrait -4.44E-23

0
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 131 > KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024
9 oct. 2016 à 13:29
Je vais donc voir tous ces termes.
Merci!
0
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 931
Modifié par Whismeril le 9/10/2016 à 18:04
Faut quand même savoir ce que tu veux, je te réponds, qu'en float, vu comment c'est code 456.7 n'existe pas et qu'en le plus proche est 456.70001.... et cette réponse ne te suffit pas.
Quand je détaille, la reponse est trop spécifique!

En plus tu as fait par toi même une conversion de d'hexa vers décimal, conversion pour laquelle la notion de poids fort et de poids faible est un pré requis, donc je ne voyait pas la nécessité de revenir dessus.
Donc le poids faible est le digit qu'en l'on multiplie par la base à la puissance 0, au final c'est celui qui à la plus petite influence sur le nombre global, en général, sur un entier le digit de poids faible influe sur +/- 1. À l'inverse, le digit de poids fort est celui à qui on appliquer la puissance la plus élevée, qui aura donc une forte influence sur le résultat.

Un octet est l'unité de base informatique, c'est 8 bits (d'ou le préfixe oct), il est majoritairement représenté sous forme d'un nombre hexadécimal de 2 caractères.

Le fait que le digit de poids faible soit à droite ou à gauche tient du fait que ce qui lu (flux ou fichier) sera placé octet par octet dans la mémoire vive et ce qui est lu en premier aura une adresse plus petite que ce qui,est lu en suivant. Ensuite c'est juste une histoire de convention, est ce qu'on calcul dans un ordre ou dans l'autre.
0
CrazyGeekMan Messages postés 871 Date d'inscription dimanche 1 novembre 2015 Statut Membre Dernière intervention 29 octobre 2022 131 > Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024
9 oct. 2016 à 19:50
Non mais je comprend que tu veux m'expliquer au mieux ce que tu connais.
Malheureusement je n'ai pas de très bonne aptitude de compréhension.
Grâce à ta dernière explication j'ai compris beaucoup plus de chose (et oui si c'est pas détaillé je suis pommé).
Mais donc je peux retenter mon calcul en inversant l'importance des puissances?
Si ce n'est pas du tout cela je ne vais pas te faire perdre ton temps puisque le problème vient de moi même. Je prendrai soin de méditer un jour sur cette question devant différents articles sur la question.
Merci pour vos efforts !
0