Bonjour,
Je cherche des cours pour comprendre comment coder des flottants dans la norme IEEE754 en base 2, en simple ou double précision et en mode arrondi, je ne comprend pas bien les mien
Merci pour votre aide
-----
Bonjour,
Je cherche des cours pour comprendre comment coder des flottants dans la norme IEEE754 en base 2, en simple ou double précision et en mode arrondi, je ne comprend pas bien les mien
Merci pour votre aide
En premier lieu, tu devrais demander de l'aide à ton prof plutôt que de venir ici.
En second lieu, as-tu chercher dans google ? Il y a beaucoup de document avec « cours IEEE754 » simplement.
L'idée est simple. Un nombre à virgule flottante est représenté par trois (ou deux si tu as un nombre non signé) parties :
- le signe
- l'exposant
- les valeurs significatives
Ce site illustrera ça:
http://babbage.cs.qc.edu/IEEE-754/Decimal.html
J'espère que cela t'aidera. Mais tu devrais vraiment aller en parler à ton prof.
Avant tout, merci beaucoup car ton site est bien pratique. Il va me permettre de vérifier mes résultats.En premier lieu, tu devrais demander de l'aide à ton prof plutôt que de venir ici.
En second lieu, as-tu chercher dans google ? Il y a beaucoup de document avec « cours IEEE754 » simplement.
L'idée est simple. Un nombre à virgule flottante est représenté par trois (ou deux si tu as un nombre non signé) parties :
- le signe
- l'exposant
- les valeurs significatives
Premièrement, je ne peux pas demander à mon prof, car je reprends les cours mercredi et l'exam est ... mercredi
Deuxièmement, j'ai cherché dans google, j'ai trouvé des choses, mais ça ne me suffit pas
Enfin, connaîtrais-tu d'autres sites, où il est expliqué, pas à pas, comment procéder, mais sur des exemples.
Je n'ai pas compris comment faire quand l'exposant est positif, car on ne peut pas utiliser : E codé=E vrai + biais.
Et j'ai pas trop compris quand il fallait changer la virgule de place dans l'écriture du nombre pour justement trouver l'exposant...
Ben ce n'est pas compiqué:
J'imagine que ce que Gre apelle "les valeurs significatives" est en fait la mantisse (un nombre inclus dans l'intervale [0,2[)
Ensuite le nombre à coder peut s'exprimer sous la forme:
(où signe = 1 ou -1)
Donc quand tu as un nombre positif, grosso modo
tu le divises par 2 e fois jusqu'a ce que le résultat obtenu soit inférieur strictement à 2, tu trouves ainsi la mantisse, le nombre de division (e) correspond à l'exposant.
Si tu as un nombre négatif tu mets le signe à -1 et tu appliques exatement la même démarche avec la valeur absolu de ce nombre.
La mantisse se code en binaire sous la forme:
1.101001001
Plus d'info sur Wikipedia.
Bon désolé j'ai dit une betise, la mantisse est en fait un nombre inclus dans l'intervale [1,2[ (et oui j'ai écris trop vite sans penser aux nombres plus petits que 1)
Donc la methode que j'ai ecrite plus haut reste valable dans la cas ou tu as un nombre plus grand ou égal à 2.
Si le nombre est inférieur strictement à 1:
Ben c'est pareil sauf que là tu le multiplie e fois jusqu'à ce qu'il soit supérieur ou égal à 1, tu trouves la mantisse, le nombre de multiplication correspond alors à l'opposè de l'exposant (exposant=-e)
La mantisse s'exprime en fait sous la forme:
1.101001001 où le premier 1 est omis (c'est toujours 1)
Voila, désolé encore pour cette erreur grossière.
Merci beaucoup Jean_Luc, je ne savais pas que le nombre de multiplication avant d'atteindre 1 pour un nombre inférieur à 1 correspondait à l'exposant et je me demandais comment faire avec les nombres supérieurs à 1... le prof nous ayant rien expliqué de tout cela
J'ai encore 3 questions, les dernières j'espère.
1) dans l'exemple que vous avez précédemment cité, vous dites que le premier 1 est toujours omis. Alors comment écrit-t-on le développement du nombre?
.101001001 ?
ou
101001001 ?
2) pour trouver toute la mantisse pour un nombre inférieur à 1, donc je commence par multiplier par 2. Dès que je dépasse 1, je compte le nombre de multiplication effectuées. Prenons par exemple 4. Si le nombre en question n'est pas périodique, ceci me permet alors de savoir quand m'arrêter dans les calculs. En effet, en simple précision, il y a 23 bits pour la mantisse, donc il me faudra 23+4 nombres. Est-ce bien cela?
3) quand un nombre est plus grand que 1, j'effectue les divions successives par 2. Mais une fois que le nombre est inférieur à 1, je fais quelle opération pour repasser au dessus de 1. Je sais qu'avec un nombre plus petit que 1, on fait -1. Là je fais +1?
J'espère avoir été claire dans mes questions
.101001001 * 2 = 1.01001001 (>= à 1, on s'arrête)
Donc Mantisse = .01001001 (On code pas le premier 1)
et exposant = -1 (une seule multiplaction)
101001001 / 2 = 10100100.1
101001001 / 2 = 1010010.01
101001001 / 2 = 101001.001
101001001 / 2 = 10100.1001
101001001 / 2 = 1010.01001
101001001 / 2 = 101.001001
101001001 / 2 = 10.1001001
101001001 / 2 = 1.01001001 (< à 2, on s'arrête)
Donc Mantisse = .01001001 (On code pas le premier 1)
et exposant = 8 (8 division)
Exemple bien choisi, même mantisse mais exposant différent.
Qu'il soit periodique ou non, cela ne change rien dans2) pour trouver toute la mantisse pour un nombre inférieur à 1, donc je commence par multiplier par 2. Dès que je dépasse 1, je compte le nombre de multiplication effectuées. Prenons par exemple 4. Si le nombre en question n'est pas périodique, ceci me permet alors de savoir quand m'arrêter dans les calculs.
tes calculs. Pour 4 par exemple il faudra faire 2 divisions pour que le nombre soit strictement inférieur à 2. On
le codera donc .0000... * 2^2 = 1*4
En simple précision il y a effectivement 23 bits pour la mantisse, 8 bits pour l'exposant et 1 bit pour le signe, ce qui fait 32 bits. Attention le bit de signe qui te dit si ton nombre est positif ou négatif, n'a rien à voir avec le bit de signe de l'exposant (codé en complément à 2) qui te dit si ton nombre en valeur absolue est > à 2 (exposant positif) ou <= à 1 (exposant négatif) ou dans [1,2[ (exposant nul)
Je ne comprends pas bien cette question, pourquoi veux-tu repasser au dessus de 1 ?
Merci pour toutes ces explications
Je crois que j'ai oublié de préciser quelque chose...
Le nombre que je cherche à coder est en base 10.
Voici le seul exemple à peu près complet qu'on a fait. Coder le nombre qui est en base 10 : 0.1
Donc, on a fait :
0.1
* 2
----
0.2
* 2
----
0.4
* 2
----
0.8
* 2
----
1.6
- 1
----
0.6
* 2
----
1.2
- 1
----
0.2
et là on remarque qu'on a une suite périodique, donc inutile de continuer les calculs.
Est-ce que l'exposant est de 4 car il y a 4 multiplications avant que le nombre soit supérieur à 1 ???
On voit que cette mantisse s'écrit : 000110001100011 ...
Alors comment fait-on pour l'écrire sous la forme 1. ..... ?
Quand on a pas une suite périodique, on doit s'arrêter au bout de 23 nombres?
Et pour coder par exemple 4.4 (qui est en base 10 toujours), je dois faire comment?
4.4 |2
2.2|2
1.1|2
0.55
En fait, là je vois pas comment faire , je vois pas quels sont les nombres qui vont constituer la mantisse. En tout cas, est-ce que je peux dire que comme il y a 3 divisions avant que le nombre soit inférieur à 1, l'exposant est de 3 ??
là je m'embrouille tout !
J'ai trouvé un site qui m'a permis de comprendre comment coder les nombres plus grands que 1. Par ex, pour 4,4 on code d'abord 4 puis 0.4 puis on accole les mantisses des deux.
J'ai trouvé comme exemple le nombre : 238.4375 dont la représentation binaire est : 11101110,0111.
Donc, par normalisation, on l'écrit sous la forme :
1,1101110011 2^7 où 7 est l'exposant.
Jusque là tout va bien.
Mais j'ai vu en cours que pour les exposants négatifs, on utilisait : Ecodé=Evrai+biais
Or, dans cet ex, on fait : 7+127=134 et on code 134
Mais pourtant ici l'exposant est positif (7) donc pourquoi utiliser cette formule? Devrait-on pas plutôt coder 7 ?
Salut,
Non l'exposant est -4 (4 multiplications)et là on remarque qu'on a une suite périodique, donc inutile de continuer les calculs.
Est-ce que l'exposant est de 4 car il y a 4 multiplications avant que le nombre soit supérieur à 1 ???
Je ne suis pas sur du résultat que tu donnes pour la mantisse ???? Je ne connais pas la méthode queOn voit que cette mantisse s'écrit : 000110001100011 ...
Alors comment fait-on pour l'écrire sous la forme 1. ..... ?
Quand on a pas une suite périodique, on doit s'arrêter au bout de 23 nombres?
tu présentes ????
Reprenons l'exemple de 0.1
0.1 * 2 = 0.2
0.2 * 2 = 0.4
0.4 * 2 = 0.8
0.8 * 2 = 1.6 (Suffisant pour déterminer l'exposant -4)
Tu trouves donc un mantisse qui est égale à 1.6 (en décimal) soit 0.6 puisque que l'on ne code pas le premier 1, mais qui n'admet pas un développement fini en binaire.
0.6 = .1001100110011001
Bien sur on ne peut que rentrer les 23 premiers chiffres après la virgule.
On remarque que la période est 1001.
Comment déterminer les bits de la mantisse ?
0.6 * 2 = [1] + 0.2
0.2 * 2 = [0] + 0.4
0.4 * 2 = [0] + 0.8
0.8 * 2 = [1] + 0.6 (Ca suffit on retombe sur 0.6)
Donc la mantisse s'ecrit (1).1001....
Note que cet exemple peut porter a confusion. La période ne recommence par forcement du début ex:
Soit 0.7 à coder en binaire:
0.7 * 2 = [1] + 0.4
0.4 * 2 = [0] + 0.8
0.8 * 2 = [1] + 0.6
0.6 * 2 = [1] + 0.2
0.2 * 2 = [0] + 0.4 (Ca suffit on retombe sur 0.4)
Donc la mantisse s'ecrit (1).10110....
Tu peux verifier tes calculs sur cette page
Oui c'est comme ca que l'on code un exposant.Mais j'ai vu en cours que pour les exposants négatifs, on utilisait : Ecodé=Evrai+biais
Or, dans cet ex, on fait : 7+127=134 et on code 134
Mais pourtant ici l'exposant est positif (7) donc pourquoi utiliser cette formule? Devrait-on pas plutôt coder 7 ?
avec biais = avec n le nombre de bit de l'exposant.
Mmm Bizarre ce que dit ton prof...
Oui cette formule est valable quelque soit l'expostant.
Ex:
expostant = 7 se code 134 (en simple precision)
Ecodé=Evrai+biais
134 = 7 + 127
expostant = -7 se code 120 (en simple precision)
Ecodé=Evrai+biais
120 = -7 + 127
Je ne vais pas revenir sur ce que dis Jean-Luc, car ce qu'il dit a l'air de qualité (je n'ai que survolé ^_^)
Cependant pour ta remarque, il fallait donc aller voir le prof avant ! C'est un peu tard pour apprendre. À cette période tu ne devrais que réviser.
Tu verras les études deviennent d'une simplicité extrême si on sait bien organiser son travail.
C'est normal !! C'est un système à virgule flottante (float).
C'est pour ça que c'est . Si tu n'as pas compris ça tu n'as rien compris aux nombres à virgule flottante.
C'est le lien que je lui ai donné à la première réponse -_-
Je sais bien Gre que j'aurais dû bosser avant mais je vais essayer de me défendre :
1) cette année j'ai tous les semestres 10 matières et toutes celles qui concernent l'informatique sont nouvelles pour moi (avant je faisais des maths pures) et me demandent beaucoup de travail, alors je ne peux pas être à jour partout.
2) les cours de ce prof sont mauvais (très très mauvais). Je sais que ça paraît bien puérile de mettre ça sur le dos du prof, mais quand je vois que juste sur la partie concernant le codage des nombres il a fait 2 grossières erreurs sachant qu'en plus on m'en a signalé d'autres, je pense que ça retranscrit ses capacités! Et le fait que même pas la moitié des élèves viennent à ses cours/TD!
Je suis à l'insa en 3ème année, avant j'ai fait prépa et fac (une petite fac à pau), et c'est la 1ère fois que je vois autant de mauvais prof rassemblés!! Je suis extrêmement déçue a tel point que je me demande si je vais y rester !
Bon, désolée j'ai une dernière question ...
Maintenant, je sais coder des nombres , j'ai vérifié avec le lien que vous m'avez donné. Mais des fois, il y a un 1 d'ajouter à la fin de la mantisse et je ne sais ni pourquoi ni quand il faut le faire ...
C'est l'arrondi non ?
Regarde la différence entre le button "Rounded" et "Not Rounded".
En effet, dis comme ça, ça semble logique, merci.
Alors si ma mantisse se termine par 00110011 admettons et si c'est une suite périodique, alors :
si je veux l'écire en mode arrondi, j'aurai : 00110011 (parce que derrière il y a 0 et pas un 1) ? ou bien en mode arrondi ajoute-t-on toujours 1, quelque soit le nombre qui suit?
Finalement, j'ai encore deux questions :
1) quel est le nombre de flottants compris entre la valeur du nombre codé 0.099 et celle de 0.1 ?
Doit-on repasser en binaire? Et que faire après?
2)Comment calculer sur machine : sqrt(a^2+y)-a avec a>0 et y petit devant a^2?
Je ne sais pas exactement comment l'arrondi est calculé. Il me semble que l'on regarde 3 ou 4 bits après le dernier. C'est comme en décimal, si tu as 0.5005 et que tu veux arrondir à 1 décimale, il te faut regarder jusqu'a la quatrième décimale pour avoir un arrdoni à 0.6.En effet, dis comme ça, ça semble logique, merci.
Alors si ma mantisse se termine par 00110011 admettons et si c'est une suite périodique, alors :
si je veux l'écire en mode arrondi, j'aurai : 00110011 (parce que derrière il y a 0 et pas un 1) ? ou bien en mode arrondi ajoute-t-on toujours 1, quelque soit le nombre qui suit?
Pour 0.099 et 0.1, l'exposant est -4 donc la pas de problème, tu exprimes la mantisse en binaire et tu fais simplement une soustraction. Je trouve 134217 nombres (simple précision). Si l'exposant est différent, là c'est plus complexe. En gros, il faut faire n décalage à droite du plus petit nombre (n étant la valeur absolue de la différence des exposant) de façon à se ramener au même exposant ensuite tu fais la soustraction (là il faut considérer le 1 de la mantisse non codé) mais ce résultat reste approché car il faut encore ajouté 2n nombres (oublié à cause du décalage).Finalement, j'ai encore deux questions :
1) quel est le nombre de flottants compris entre la valeur du nombre codé 0.099 et celle de 0.1 ?
Doit-on repasser en binaire? Et que faire après?
Ben là, si y est trop petit il risque d'être négliger par rapport à a^2, autrement dit l'addition donnera , le resultat de sera donc 0. C'est le problème de la virgule flotante, il faut manipuler des nombres du même ordre de grandeur pour éviter ce genre de problème.2)Comment calculer sur machine : sqrt(a^2+y)-a avec a>0 et y petit devant a^2?
Par exemple pour calculer , si B<<A et C>1 il sera plus judicieux de calculer .
Pour l'arrondi on utilise souvent l'arrondi vers le pair le plus proche (round to even), appelé aussi l'arrondi du banquier (banker's rounding). Cependant la manière d'arrondir n'est pas spécifiée par la norme. C'est ce qui provoque d'ailleurs des problèmes de compatibilité de calcul dans des outils scientifiques de très haute précision. Voici l'illustration du round to evenEn effet, dis comme ça, ça semble logique, merci.
Alors si ma mantisse se termine par 00110011 admettons et si c'est une suite périodique, alors :
si je veux l'écire en mode arrondi, j'aurai : 00110011 (parce que derrière il y a 0 et pas un 1) ? ou bien en mode arrondi ajoute-t-on toujours 1, quelque soit le nombre qui suit?[...]
En arrondissant à 4 chiffres après la virgule, on regarde le 5e.Code:1.0010000000000 1.0010 pas de perte 1.0011000000000 1.0011 pas de perte 1.0010000101000 1.0010 perte 1.0011000101000 1.0011 perte 1.0010100000000 1.0010 perte 1.0011100000000 1.0100 ajout 1.0010100101000 1.0011 ajout 1.0011100101000 1.0100 ajout
Si c'est un 0 on tronque, si c'est un 1 on augmente de 1 le 4ieme
(Ça c'est la méthode qu'on apprend classiquement en classe).
Mais pour respecter le principe d'équilibre (autant de perte que de gain), il y a une autre règles.
J'ai appuyé sur le bouton envoi au lieu de prévisualisation -_-
Je disais donc:
Si ton (n+1)e chiffre est un 1 suivi de 0, alors tu fais la modification qui mène vers un chiffre pair. En binaire, ça veut dire vers 0. On tend donc vers une terminaison avec un 0.
C'est pour ça que
1.0011100000000 (1.21875)
a été arrondi à
1.0100 (1.25)
de manière conventionnellw (on avait un 1 donc on a fait un ajout) alors que
1.0010100000000 (1.15625)
a été arrondi à
1.0010 (1.125)
à l'aide d'une perte tandis que de manière conventionnelle on l'aurait arrondi à
1.0011 (1.1875)
Tu as wikipedia qui offre un article dessus. Mais il ne parle que de l'arrondi pour des nombres décimaux je crois.
Ce système a l'avantage de préserver un équilibre entre gain et perte. C'est pour ça qu'il est très utilisé car les erreurs d'arrondis ont tendance à disparaître.
http://en.wikipedia.org/wiki/Roundin...to-even_method
Euh non...
0.5005 arrondi à 1 décimale ça donne 0.5 car on a un zéro en deuxième position. C'est l'arrondi classique de [i]n[/n] à p décimales
où est la partie entière de x
En reprenant la méthode que j'ai cité précedemment si tu avais 0.5500 tu arrondirais à 0.6 avec l'arrondi du banquier (ajout), alors que 0.4500 s'arrondirait à 0.4 (perte). Pour 0.5005 arrondit à une décimale, ça ne changerait rien. Par contre, arrondi à 3 décimales ça donne 0.500 (perte) ce qui n'est pas la méthode habituellement enseigné en cours de math pour les arrondis.
Bon j'espère que ça a aidé ^_^ vu que c'est Jean_luc qui a fait tout le boulot jusqu'à là.
Eh bien merci beaucoup à tous les deux, si je réussis demain, ça sera grâce à vous
Eh bien Merci Gre pour ce cours sur les arrondis. C'est vrai que je ne m'etais jamais vraiment posé la question. Au moins j'ai apris quelque chose.
Loulou je te souhaite bonne chance pour ton exam et j'espère qu'on t'a pas trop embrouillé.
C'est un réel problème cet histoire d'arrondi en fait.
Ça a des effets surprenants. Pour reprendre les exemples d'un collègue réputé pour ses présentations eclairantes:
- 3 x 2. est différent 2 x 3. en C++
- .30 + .01 - .30 - .01 ne donne pas 0 avec ExcelCode:#include <iostream> using namespace std; int main() { if(2*.3==3*.2) cout<<"Mais oui, voyons!"<<endl; else cout<<"Ah non!"<<endl; }
- Ce code très naturel fourni des résultats faux avec une probabilité importante
Avec 100000 calculs, mon collègue n'a trouvé que 20347 fois le bon résultat sur une somme de 100 nombres à virgule flottante. Il a trouvé 33 résultats différents ! Étonnant non Une bonne procédure de sommation est enCode:float somme(float t[], int n) { float s=0.; for(int i=0; i<n; i++) s+=t[i]; return s; }
En tout cas, voici beaucoup de surprises innattendues la première fois qu'on rencontre ça.
Je suis bien d'accord, à chaque fois être obliger de comparer des valeurs absolues de différence pour tester "l'égalité" de 2 flottans c'est pénible et parfois piégeux.C'est un réel problème cet histoire d'arrondi en fait.
Et pourtant en float (simple précision) ça marche bien (du moins ce calcul là).- 3 x 2. est différent 2 x 3. en C++
En C++ non plus d'ailleurs, l'erreur est même grande de l'ordre de 8.7e-18 !- .30 + .01 - .30 - .01 ne donne pas 0 avec Excel
Comment peut-on faire un procédure de sommation en ?[...]
Une bonne procédure de sommation est en
Non non. L'as tu executé ?
La preuve en image.
En fait, la bonne procédure pour être sûr d'une somme consiste à toujours additionner les 2 plus petits ensembles. La somme des deux plus petits nombres est à nouveau à recomparer avec les autres. La technique naïve est donc quadratique. Mais on peut utiliser un heap (un tas) pour ça. La procédure sure est donc en en utilisant cette structure. Vu que tu ne veux pas que ta somme soit fausse 1 fois sur 2 lorsque tu as besoin de 4 chiffres significatifs de précision, il faut passer par là ^_^