J'obtiens 75834 soit le nombre à l'envers. Ce que je veux dire, c'est que depuis dans mon code je manipule directement les valeurs de la mantisse. Donc je n'aurais pas de chiffres supérieurs à 1 parce que je fais:
Est ce que tu veux dire que c'est comme si ça s reconvertissait automatiquement?? Désolé je suis un peu perdu...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 manti=(n)&(0x007FFFFF); //Je récupère la mantisse
Tu peux donner un peu plus de détails ou un exemple stp? Je n'ai pas besoin de code, juste de la logique.
Parce que si comme tu le dis je n'ai pas besoin de travailler directement avec les bits, je n'aurais pas une valeur complètement différente si je récupère directement la mantisse, sans placer la virgule? Je pars du fait de la conversion du binaire en décimal. Avant et après la virgule, on a des règles différentes en convertissant manuellement.
Ce que je veux dire, c'est :
- Que « i » est une variable codée en binaire dans la mémoire de l'ordinateur, de la même façon que l'est ton float ;
- Qu'à aucun moment, je ne suis allé manipuler les bits directement ;
- Que j'ai quand même obtenu le résultat escompté à l'écran, sans utiliser printf (même s'il est écrit à l'envers).
Donc, étant donné que le problème est purement algébrique, comme dit plus haut, tu n'as aucun besoin d'aller extraire les champs de bit à la main comme tu le fais.
Le programme que je t'ai donné fait la moitié du travail. D'une manière générale, pour extraire des chiffres un par un, il faut les faire passer « de l'autre côté de la virgule », de manière à pouvoir le distinguer des autres. Si tes chiffres se trouvent à gauche de la virgule, tu divises par 10 (ou plus généralement, par la base de ton choix), pour en faire passer à droite et tu récupères sa valeur grâce au modulo 10.
Dans le même esprit, lorsqu'il ne tu n'as que des chiffres à droite de la virgule (donc « 0,xxxx » ), tu multiplies par 10 pour en faire passer à gauche, et tu récupère sa valeur en considérant la partie entière.
Ça signifie également que c'est par divisions ou multiplications successives que tu vas parvenir à tes fins. Donc, le contenu de ton float sera altéré à chaque itération et c'est normal.
Donc j'ai un nombre en binaire interprété par la machine (disons 26539) qui n'a rien à voir avec la valeur de mon float. Qu'est ce que je dois faire passer de l'autre côté de la virgule??? SI j'ai un exposant égal à 3 par exemple, ça signifie que je dois faire 9%10 et ainsi de suite???
Il faut absolument que tu y réfléchisses un peu par toi-même, parce que c'est le but de l'exercice. Le code qui va derrière, une fois compris le principe, n'a aucun intérêt en lui-même. Je t'ai expliqué deux fois ce qu'il fallait faire passer de l'autre côté de la virgule. Relis bien mes posts.
Pour te mettre sur la voie, voici un autre exemple. Imaginons que tu travailles sur papier et que tu n'aies pas du tout d'ordinateur (donc, on met de côté le langage C pour le moment). Tu n'as pas non plus de calculatrice. Juste du papier brouillon et un crayon en état de marche.
Tu me proposes le nombre 26539 en décimal (base 10). Quelle serait sa valeur en base 7 et comment t'y prendrais-tu pour la trouver ?
On s'en fiche, dans ce cas précis. C'est ta machine qui gère la valeur du nombre. Tu n'as pas besoin de manipuler directement ces exposants pour en faire la représentation en décimal, sauf si tu veux que cet exposant apparaisse à l'écran.SI j'ai un exposant égal à 3 par exemple, ça signifie que je dois faire 9%10 et ainsi de suite???
Il faut bien se souvenir que la base d'un nombre n'est qu'une manière de le représenter et que si tu changes cette base, tu ne changes pas la valeur du nombre lui-même. C'est un peu comme utiliser les chiffres romains : si j'écris « 6 » ou « VI », la valeur numérique reste rigoureusement identique.
Pour ce cas là je ferais comme d'habitude des divisions successives jusqu'à trouver zéro en examinant les restes. Mais dans mon cas, avec la mantisse, il s'agit d'un nombre réel, pas d'un entier, et sans la virgule en plus. Donc la valeur interprétée par la machine est différente de la valeur en base 10 réelle. C'est ta logique que je ne comprends pas, pas le code.
-Tu parles de conversion de bases, mais c'est de quelle base vers quelle base vu que la machine interprete le tout???
-Pourquoi fallait-il que je sache comment sont stockés les float en mémoire alors?
-Comment je peux savoir si c'est "a gauche" ou "à droite" de la virgule si je connais pas l'exposant? Dans mon code je trouve l'exposant cependant....
Tu veux afficher un nombre flottant F avec une précision de n chiffres après la virgule. Si ton exercice revient à simuler un printf(), on peut supposer que tu as déjà codé l'affichage d'un entier.
On peut partir sur le principe (à adapter pour tenir compte du cas des valeurs négatives) :
Exemple : F = 2.8759999275207521- afficher la partie entière de F 2- afficher le point décimal 3- prendre la partie fractionnaire de F et la multiplier n fois par 10 4- arrondir en ajoutant 0.5 5- afficher la partie entière du nombre obtenu
1- sortir 2 2- sortir . 3- Partie fractionnaire : 0.875999927520752 pour n = 3 multiplier par 10^3 -> 875.999927520752 pour n = 7 multiplier par 10^7 -> 8759999.27520752 4- pour n = 3 -> 876.499927520752 pour n = 7 -> 8759999.77520752 5- sortir pour n = 3 -> 876 sortir pour n = 7 -> 8759999 Affichage pour n = 3 -> 2.876 pour n = 7 -> 2.8759999
Cependant est-ce que ce serait possible, comme le printf original, d'afficher pour n=7 2.876000? C'est juste pour être aussi fidèle que possible.
Bien sûr. Ce sont des zéros non significatifs. Le plus « dur » est de les masquer. Une fois que tu as réussi à obtenir les trois premiers chiffres, rien ne t'empêche de combler le reste avec des zéros.
Oui mais je veux que ça marche aussi s'il y a 4 chiffres significatifs.
Par exemple pour 2.876, j'affiche 2,8760000 et pour 2.8765 2.8765000. Donc en gros, est-ce que c'est possible de trouver le nombre de chiffrs significatifs?
Je pensais pouvoir le faire en trouvant l'exposant mais ça complique tout et n'arrange pas grand chose.
Par de manière absolue pour les raisons que l'on a exposé au départ. Le nombre « 2.876 » ne pouvant être représenté de manière finie en binaire, la valeur approchée la plus proche qui va se trouver dans un double par exemple correspondra à « 2.875999999999999801048033987171947956085205078125 ». Donc rien ne te permet de savoir a priori s'il s'agit en fait de « 2.876 » ou si c'est ce nombre exact que tu as voulu coder.
Le seul moyen de s'en sortir est de fixer une précision arbitraire. Donc, par exemple, six chiffres après la virgule dans le cas qui nous intéresse.
Dans ce cas, tu vas obtenir « 2,785999 ». À ce stade, tu fais comme indiqué dans mes commentaires précédents : tu examines la décimale suivante et tu arrondis si nécessaire. Dans le cas présent, cette décimale suivante est encore un « 9 ».
Comme tu as multiplié par 10⁶ pour sortir tous les chiffres d'un coup, tu obtiens 2785999,9. Tu arrondis donc à 2786000 et tu ignores (ou pas) les zéros à l'affichage. Si tu avais obtenu « 2785999,1 » tu aurais arrondi par défaut et tu aurais gardé les « 9 ».
Partager