Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1488 connectés 

  FORUM HardWare.fr
  Programmation
  Divers

  déchiffrer encodage de nombre réels

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

déchiffrer encodage de nombre réels

n°2317591
rat de com​bat
attention rongeur méchant!
Posté le 02-07-2018 à 22:08:30  profilanswer
 

:hello:  
 
J'ai deux octets qui représentent un nombre réel et je n'arrive pas à trouver comment passer des deux octets au nombre. Ce n'est à priori pas du IEEE754 ou ce genre de truc. On voit une certaine logique mais j'ai beau chercher, je ne trouve pas la formule. :( Quelqu'un à une idée? :o  
 
Dans la liste la première colonne indique le nombre en décimal, ensuite viennent les deux octets en héxa et binaire. Je sais pas si c'est du big- ou little-endian, ni si c'est MSB-LSB ou peut-être l'inverse.
 


 0.0 0x00 0x00 00000000 00000000
 0.1 0x80 0x3f 10000000 00111111
 0.2 0x00 0x40 00000000 01000000
 0.3 0x40 0x40 01000000 01000000
 0.4 0x80 0x40 10000000 01000000
 0.5 0xa0 0x40 10100000 01000000
 0.6 0xc0 0x41 11000000 01000001
 0.7 0xe0 0x41 11100000 01000001
 0.8 0x00 0x41 00000000 01000001
 0.9 0x10 0x41 00010000 01000001
 1.0 0x20 0x41 00100000 01000001
 1.1 0x30 0x41 00110000 01000001
 1.2 0x40 0x41 01000000 01000001
 1.3 0x50 0x41 01010000 01000001
 1.4 0x60 0x41 01100000 01000001
 1.5 0x70 0x41 01110000 01000001
 2.0 0xa0 0x41 10100000 01000001
 3.0 0xf0 0x41 11110000 01000001
 3.2 0x00 0x42 00000000 01000010
 4.0 0x20 0x42 00100000 01000010
 5.0 0x48 0x42 01001000 01000010
 6.0 0x70 0x42 01110000 01000010
 7.0 0x8c 0x42 10001100 01000010
 8.0 0xa0 0x42 10100000 01000010
 9.0 0xb4 0x42 10110100 01000010
10.0 0xc8 0x42 11001000 01000010
11.0 0xdc 0x42 11011100 01000010
12.0 0xf0 0x42 11110000 01000010
13.0 0x02 0x43 00000010 01000011
14.0 0x0c 0x43 00001100 01000011
15.0 0x16 0x43 00010110 01000011
16.0 0x20 0x43 00100000 01000011
17.0 0x2a 0x43 00101010 01000011


---------------
Si vous ouvrez un sujet merci de ne pas le "laisser mourir" subitement et de le marquer comme "résolu" le cas échéant!
mood
Publicité
Posté le 02-07-2018 à 22:08:30  profilanswer
 

n°2317614
MaybeEijOr​Not
but someone at least
Posté le 03-07-2018 à 21:40:53  profilanswer
 

Je suis à peu près sûr que le dernier bit (en partant de la droite) du second octet est le signe. :D

 

D'après l'exemple du nombre 0.1, les 7 autres bits (que j’appellerai à tord "septuplet" ) correspondent à l'exposant, ainsi dans cet exemple on trouve :

 

septuplet = 1*2^0 + 1*2^1 + 1*2^2 + 1*2^3 + 1*2^4 + 1*2^5 + 0*2^6 = 63
offset = 2^6 - 1 = 64 - 1 = 63
exp = septuplet - offset = 63 - 63 = 0

 

L'exposant étant égale à 0, on ne déplace pas la virgule : 1.0000000
octet = 1*2^0 = 1
Il faut alors diviser l'octet par 10 pour obtenir 0.1.

 


On retrouve cette logique pour d'autres comme 0.6 (11000000) (01000001) :
septuplet = 1*2^0 + 0*2^1 + 0*2^2 + 0*2^3 + 0*2^4 + 0*2^5 + 1*2^6 = 65
offset = 2^6 - 1 = 64 - 1 = 63
exp = septuplet - offset = 65 - 63 = 2

 

L'exposant étant égale à 2, on place la virgule de 2 fois vers la droite : 110.000000
octet = 0*2^0 + 1*2^1 + 1*2^2 = 2 + 4 = 6
Il faut alors diviser l'octet par 10 pour obtenir 0.6.

 


Ou 0.7 (11100000) (01000001) :
septuplet = 1*2^0 + 0*2^1 + 0*2^2 + 0*2^3 + 0*2^4 + 0*2^5 + 1*2^6 = 65
offset = 2^6 - 1 = 64 - 1 = 63
exp = septuplet - offset = 65 - 63 = 2

 

L'exposant étant égale à 2, on place la virgule de 2 fois vers la droite : 111.000000
octet = 1*2^0 + 1*2^1 + 1*2^2 =1 + 2 + 4 = 7
Il faut alors diviser l'octet par 10 pour obtenir 0.7.

 


Pour des cas comme 1.1, 1.2, 1.3, 1.4, 1.5 tu remarques que si tu remplaces le premier bit (0) de l'octet par 1 et que tu gardes les 4 premiers tu obtiens :
1011 = 1*2^0 + 1*2^1 + 0*2^2 + 1*2^3 = 1 + 2 + 0 + 8 = 11
1100 = 0*2^0 + 0*2^1 + 1*2^2 + 1*2^3 = 0 + 0 + 4 + 8 = 12
1101 = 1*2^0 + 0*2^1 + 1*2^2 + 1*2^3 = 1 + 0 + 4 + 8 = 13
1110 = 0*2^0 + 1*2^1 + 1*2^2 + 1*2^3 = 0 + 2 + 4 + 8 = 14
1111 = 1*2^0 + 1*2^1 + 1*2^2 + 1*2^3 = 1 + 2 + 4 + 8 = 15

 

Mais pourtant leur exposant est égale à 2 donc je ne vois pas comment s'en accommoder.

  

Bref juste des pistes, pas trouvé de règle universelle.


Message édité par MaybeEijOrNot le 03-07-2018 à 21:41:57

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2317631
MaybeEijOr​Not
but someone at least
Posté le 04-07-2018 à 13:58:25  profilanswer
 

Bon j'ai trouvé, en fait faut décaler deux 2 bits la "virgule" pour chaque valeur de l'exposant. Si le premier octet commence par un 0 alors on le remplace par un 1 et on décale d'un bit supplémentaire la virgule.
Je dirai qu'on est entre le système de virgule fixe et le système de virgule flottante.
 
En résolution par Excel ça donne : https://uptobox.com/rufqfejyjk3m


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2317634
rat de com​bat
attention rongeur méchant!
Posté le 04-07-2018 à 15:35:05  profilanswer
 

Merci beaucoup!! :jap: Ça a l'air plutôt compliqué, je regarderai ta solution quand je serai plus concentré. :o

n°2317652
TotalRecal​l
Posté le 04-07-2018 à 18:17:50  profilanswer
 

T'as géré [:implosion du tibia]
Enfin si ta solution marche vraiment :o
Ca ressemble à quelque chose de connu ce format chelou ?


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
n°2317653
MaybeEijOr​Not
but someone at least
Posté le 04-07-2018 à 19:04:50  profilanswer
 

Aucune idée, hier, avant de chercher des infos sur le net, je connaissais que de nom "virgule flottante" et "virgule fixe" et j'avais vaguement une idée de comment ça fonctionnait. Donc il ne faut pas trop m'en demander. :D  
 
De ce que j'ai compris des nombres à virgule flottante, tu écris ton nombre sous forme scientifique on va dire en codant sur un nombre prédéfini de bits l'exposant, le nombre et le signe.
Dans un nombre à virgule fixe, tu codes la partie entière d'un nombre sur un nombre prédéfini de bits, la partie décimale sur un autre nombre prédéfini de bits et éventuellement le signe.
Ici, la personne a codé sur un bit la virgule (bon jusque là ça va), sur un nombre prédéfini de bits le nombre de bits qu'il faudra lire pour déterminer le nombre. La personne a alloué 7 bits soit 2^6=64 décalages, sachant qu'on décale de 2 bits à chaque fois, soit un décalage de 128 bits alors que le nombre est codé au maximum sur 8 bits. Bref aucun intérêt, de plus pour économiser des bits, la personne a introduit la notion de bit caché qui n'a du sens que dans l'utilisation de la virgule flottante.
Le pire là-dedans, c'est que le décalage de lecture des bits ne sert strictement à rien puisque les bits libérés ne sont pas utilisés. :lol:  
 
 
Sinon, oui, les formules dans la colonne "bit" de la partie "mantisse" sont imbuvables car elles servent à écrire mon octet de "mantisse" (de haut vers le bas) en lisant l'octet droit de bas en haut à partir du décalage calculé tout en modifiant l'éventuel 0 de début par 1 (et de par ce fait doit réajuster le décalage par rapport à celui calculé par l'exposant).
J'ai essayé avec une bonne partie des exemples proposés et ça fonctionnait à chaque fois.
 
Et pour trouver la solution, il faut d'abord commencer par analyser les cas particuliers que sont le "0" et le "1" (qui ici vaut 0.1 puisqu'en fait on divise toujours l'entier trouvé par 10 pour avoir un nombre décimal). Puis observer les redondances : le 0 sur le deuxième octet qui se répète à chaque fois --> signe, la moins grande variabilité des valeurs de bits dans le deuxième octet --> exposant, la répartition de la variabilité des bits de l'octet de gauche (variable que sur les premiers bits au début, puis plus on descend plus ça varie sur un nombre de bits important) --> nombre (car d'une manière générale les bits varient plus que sur l'autre octet) dont la partie intéressante se trouve à gauche (car plus le nombre grandit, plus les bits de droites varient).
 
 
Voilà voilà, j'attends ma médaille en chocolat. :whistle:


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2317657
rat de com​bat
attention rongeur méchant!
Posté le 04-07-2018 à 21:29:25  profilanswer
 

Bon, je pense qu'on a raté un truc tout les deux. Après y avoir passé bien du temps j'ai réussi à pondre un décodeur, sauf que ce dernier marche sur tout les exemples sauf deux (0.6 et 0.7) - et pour ces deux là ton tableau ne fonctionne pas non plus. WTF? Je vérifierai que c'est pas une erreur de copier-coller...
 
Bon je donne mon code actuell mais ne vous moquez pas, c'est la première fois que je touche à ces histoires de virgule flottante et toussa et j'ai vraiment eu du mal. :o

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. char * tobin(unsigned int val) //j'ai jamais dit que c'était élégant...
  4. {
  5. int i=0;
  6. static char c[16]={'0'};
  7. for(i=0;i<16;i++)
  8. {
  9.  if(val&(1<<0))
  10.   c[15-i]='1';
  11.  else
  12.   c[15-i]='0';
  13.  val>>=1;
  14. }
  15. return c;
  16. }
  17. float decode(const unsigned char byte1, const unsigned char byte2)
  18. {
  19. //printf("\nbyte1: 0x%02x   byte2: 0x%02x\n", byte1, byte2);
  20. unsigned char sign=byte2>>7;
  21. unsigned char exponent=(byte2&0x7F);
  22. unsigned char mantissa=byte1;
  23. //printf("sign: %d   exp_raw: 0x%02x (%d)   mantissa: 0x%02x=0b%s\n", sign, exponent, exponent, mantissa, tobin(mantissa));
  24. if(exponent<63)
  25.  return 0.0; //?
  26. else
  27.  exponent-=63;
  28. exponent*=2; //!!
  29. if((mantissa&(1<<7))==0)
  30. {
  31.  //printf("adding 1\n" );
  32.  mantissa|=1<<7;
  33.  exponent--;
  34. }
  35. //printf("sign: %d   exp: 0x%02x (%d)  mantissa: 0x%02x=0b%s\n", sign, exponent, exponent, mantissa, tobin(mantissa));
  36. int i;
  37. float f=1;
  38. while(exponent--)
  39.  f*=2;
  40. //printf("initial f is %f\n", f);
  41. float val=0;
  42. for(i=7;i>=0;i--)
  43. {
  44.  if(mantissa&(1<<i))
  45.   val+=f;
  46.  f/=2;
  47. }
  48. return (sign)?(-val/10):(val/10);
  49. }
  50. int main(void)
  51. {
  52. printf("0.0->%f\n", decode(0x00, 0x00));
  53. printf("0.1->%f\n", decode(0x80, 0x3f));
  54. printf("0.2->%f\n", decode(0x00, 0x40));
  55. printf("0.3->%f\n", decode(0x40, 0x40));
  56. printf("0.4->%f\n", decode(0x80, 0x40));
  57. printf("0.5->%f\n", decode(0xa0, 0x40));
  58. printf("0.6->%f\n", decode(0xc0, 0x41)); //2.4
  59. printf("0.7->%f\n", decode(0xe0, 0x41)); //2.8
  60. printf("0.8->%f\n", decode(0x00, 0x41));
  61. printf("0.9->%f\n", decode(0x10, 0x41));
  62. printf("1.0->%f\n", decode(0x20, 0x41));
  63. printf("1.1->%f\n", decode(0x30, 0x41));
  64. printf("1.2->%f\n", decode(0x40, 0x41));
  65. printf("1.3->%f\n", decode(0x50, 0x41));
  66. printf("1.4->%f\n", decode(0x60, 0x41));
  67. printf("1.5->%f\n", decode(0x70, 0x41));
  68. printf("2.0->%f\n", decode(0xa0, 0x41));
  69. printf("3.0->%f\n", decode(0xf0, 0x41));
  70. printf("3.2->%f\n", decode(0x00, 0x42));
  71. printf("4.0->%f\n", decode(0x20, 0x42));
  72. printf("5.0->%f\n", decode(0x48, 0x42));
  73. printf("6.0->%f\n", decode(0x70, 0x42));
  74. printf("7.0->%f\n", decode(0x8c, 0x42));
  75. printf("8.0->%f\n", decode(0xa0, 0x42));
  76. printf("9.0->%f\n", decode(0xb4, 0x42));
  77. printf("10.0->%f\n", decode(0xc8, 0x42));
  78. printf("11.0->%f\n", decode(0xdc, 0x42));
  79. printf("12.0->%f\n", decode(0xf0, 0x42));
  80. printf("13.0->%f\n", decode(0x02, 0x43));
  81. printf("14.0->%f\n", decode(0x0c, 0x43));
  82. printf("15.0->%f\n", decode(0x16, 0x43));
  83. printf("16.0->%f\n", decode(0x20, 0x43));
  84. printf("17.0->%f\n", decode(0x2a, 0x43));
  85. return 0;
  86. }

n°2317658
MaybeEijOr​Not
but someone at least
Posté le 04-07-2018 à 21:45:36  profilanswer
 

Je viens de vérifier, en effet, c'est aussi les deux seuls exemples qui ne fonctionnent pas dans mon tableau.
Pour 0.6 et 0.7 on remarque que si on remplace l'exposant par le précédent (01000000) cela fonctionne.

 

Néanmoins, comme je l'ai pointé dans mon message précédent, ce codage me semble complètement absurde. Il doit donc y avoir une subtilité qui nous échappe, n'aurais-tu pas d'autres exemples ?

 


EDIT : au passage, je précise qu'en fait les nombres signés ne se gèrent pas simplement avec "0" = + et "1" = -, lorsque le nombre est négatif, sa valeur est le complément à 1, ce qui permet de faciliter les opérations en binaire. (je précise car j'ai fait l'erreur dans mon excel)

Message cité 1 fois
Message édité par MaybeEijOrNot le 04-07-2018 à 21:53:18

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2317660
rat de com​bat
attention rongeur méchant!
Posté le 04-07-2018 à 21:52:42  profilanswer
 

MaybeEijOrNot a écrit :

Je viens de vérifier, en effet, c'est aussi les deux seuls exemples qui ne fonctionnent pas dans mon tableau.
Pour 0.6 et 0.7 on remarque que si on remplace l'exposant par le précédent (01000000) cela fonctionne.

Ah tiens, ça soutient la thèse de l'erreur de copier-coller. Je vérifierai et je peux produire d'autres exemples, mais plus aujourd'hui, j'en ai marre là...


---------------
Si vous ouvrez un sujet merci de ne pas le "laisser mourir" subitement et de le marquer comme "résolu" le cas échéant!
n°2317661
MaybeEijOr​Not
but someone at least
Posté le 04-07-2018 à 21:54:46  profilanswer
 

Ah ok l'erreur de copier/coller c'est dans l'exemple. Je croyais que tu parlais de copier/coller dans le programme.

 

Sinon, pour ta culture (comme pour la mienne), j'ai édité mon message précédent à propos des nombres signés.

 

EDIT : puis j'édite celui là.
Et j'ajoute aussi pour ceux qui découvriraient les virgules flottantes, que le gros désavantage de ce codage est celui de ne pas stocker une valeur exacte mais une valeur approchée (après le premier chiffre, on utilise un développement limité). Faut quand même le souligner.

Message cité 1 fois
Message édité par MaybeEijOrNot le 04-07-2018 à 22:03:17

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
mood
Publicité
Posté le 04-07-2018 à 21:54:46  profilanswer
 

n°2317662
rat de com​bat
attention rongeur méchant!
Posté le 04-07-2018 à 22:04:37  profilanswer
 

Ah oui, le complément à 1 (ou à 2?), ça me dit quelque chose. Après dans mon application les nombres seront toujours positifs de toute façon, je peux pas générer de nombres négatifs.


---------------
Si vous ouvrez un sujet merci de ne pas le "laisser mourir" subitement et de le marquer comme "résolu" le cas échéant!
n°2317663
MaybeEijOr​Not
but someone at least
Posté le 04-07-2018 à 22:13:55  profilanswer
 

Je suis tombé sur complément à 1 mais oui ce doit être complément à 2 puisque c'est le complément à 2 qui est utilisé pour faire une soustraction.

 

EDIT : je ne raconte pas le nombre de choses différentes que j'ai lu sur les virgules flottantes. Même si il existe plusieurs normes, je pense que certains sites se plantent. :/

 

EDIT2 : (soirée édit)
C'est peut-être quand même le complément à 1, car pour afficher la valeur il faut la calculer, donc si on stocke le complément à 1, il suffit de refaire un complément à 1 pour afficher la valeur et pour faire la soustraction il suffit alors d'ajouter le complément à 1 et ajouter 1. Tandis que si on stocke le complément à 2 il faut d'abord faire une soustraction de 1 pour ensuite refaire un complément à 1 pour afficher la valeur. Ce qui ajoute des calculs supplémentaires. Alors après c'est juste un avis qui m'est venu en tête en me brossant les dents. À voir si c'est documenté.


Message édité par MaybeEijOrNot le 04-07-2018 à 22:38:59

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2317707
rat de com​bat
attention rongeur méchant!
Posté le 05-07-2018 à 18:42:20  profilanswer
 

J'ai vérifié, il y avait bien une erreur de copier-coller pour 0.6 et 0.7, désolé. :o
 
Voici d'autres exemples. Mon code fonctionne très bien, moi ça me suffit. Encore merci pour ton aide. :jap:  

18.0 0x34 0x43 00110100 01000011
18.1 0x35 0x43 00110101 01000011
18.2 0x36 0x43 00110110 01000011
18.3 0x37 0x43 00110111 01000011
18.4 0x38 0x43 00111000 01000011
18.5 0x39 0x43 00111001 01000011
18.6 0x3a 0x43 00111010 01000011
18.7 0x3b 0x43 00111011 01000011
18.8 0x3c 0x43 00111100 01000011
18.9 0x3d 0x43 00111101 01000011
19.0 0x3e 0x43 00111110 01000011
20.0 0x48 0x43 01001000 01000011
21.0 0x52 0x43 01010010 01000011
22.0 0x5c 0x43 01011100 01000011
25.0 0x7a 0x43 01111010 01000011
30.0 0x96 0x43 10010110 01000011

n°2317709
MaybeEijOr​Not
but someone at least
Posté le 05-07-2018 à 21:01:22  profilanswer
 

Tu n'as pas de nombre avec plus d'une décimale ?
Je ne sais pas d'où tu sors ces données, mais ce serait intéressant de voir un exemple négatif même si ça n'a pas de sens dans le cadre de ton appli. Si un bit de signe est utilisé c'est bien qu'on doit pouvoir générer des nombres négatifs.
 
 
Sinon, attention dans les commentaires de ton code, j'ai utilisé les termes d'exposant et de mantisse car dans un premier temps j'étais parti sur un modèle de virgule flottante. N'étant pas dans un vrai modèle de virgule flottante, ces termes peuvent prêter à confusion.
Quand l'exposant est inférieur à 63, on passe dans le négatif, cela permet d'opérer un décalage dans l'autre sens, c'est pourquoi il serait intéressant de voir des exemples avec plus de décimales.
Tout comme le traitement du signe, un exemple négatif permettrait de voir ce qu'il en est.
 
Et autrement à propos de ton code, je n'ai même pas réfléchi comment j'aurai fait. Déjà à la base je faisais les calculs de tête, puis quand j'ai vu que ça fonctionnait bien, je me suis dit "la flemme d'expliciter clairement par écrit". Étant au taf, je me suis dit qu'Excel était encore ce qui me prendrait le moins temps pour partager la méthode de manière formelle. Puis je n'ai jamais vraiment fait de C et ça remonte à trop longtemps donc je ne ferai pas de commentaire sur comment coder ça au plus propre. :o  
 
 
Par contre, la classe, j'arrive à trouver la solution, même avec des données erronées. :sol:  :whistle:


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2317710
rat de com​bat
attention rongeur méchant!
Posté le 05-07-2018 à 21:38:23  profilanswer
 

Des données avec plus d'une décimale je peux peut-être en produire, par contre je n'aurai pas la valeur décimale exacte. Les nombres négatifs n'ont (dans cette application) aucun sens donc je ne peux pas en produire, désolé. Du coup les exposants <63 ça peut m'être assez égal. :whistle:  
 
Merci concernant les remarques de vocabulaire. Je n'ai pas encore compris la différence entre ce truc et la "vraie" virgule flottante, pour moi c'est bien ça. :??:  
 
Mon week-end s'annonce chargé, j'essayerai de fournir d'autres données la semaine prochaine, à voir. :jap: Il faudra aussi que je modifie mon code car en fait c'est 4 octets et non deux, mais le principe de calcul qu'on a trouvé fonctionne toujours (si on fait attention à l'ordre des octets).


---------------
Si vous ouvrez un sujet merci de ne pas le "laisser mourir" subitement et de le marquer comme "résolu" le cas échéant!
n°2317712
MaybeEijOr​Not
but someone at least
Posté le 05-07-2018 à 22:37:51  profilanswer
 

MaybeEijOrNot a écrit :

Et j'ajoute aussi pour ceux qui découvriraient les virgules flottantes, que le gros désavantage de ce codage est celui de ne pas stocker une valeur exacte mais une valeur approchée (après le premier chiffre, on utilise un développement limité). Faut quand même le souligner.


 
La vraie virgule flottante c'est plus compliqué que ce que l'on a ici. Je ne vais pas détailler, d'ailleurs j'ai toujours un doute au niveau des bases utilisées en fonction de l'étape.
 
Et non rien ne presse, au contraire, j'ai plein de boulot qui m'attend, ça serait bien que j'arrête de me distraire. :(  
Mais si je suis redemandeur c'est que j'apprends comme ça. J'ai fait le choix de ne pas faire mes études dans l'informatique et/ou le développement donc à chaque fois qu'un problème est posé ça me permet d'approfondir mes connaissances. :)


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2317813
rat de com​bat
attention rongeur méchant!
Posté le 09-07-2018 à 19:01:07  profilanswer
 

Voici le code final (j'espère :o ) avec 4 exemples à 4 octets (à la fin). C'est le mieux que je puisse faire concernant plus de décimales...

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. float decode(const unsigned char byte1, const unsigned char byte2, const unsigned char byte3, const unsigned char byte4)
  4. {
  5. unsigned char sign=byte4>>7;
  6. unsigned char exponent=(byte4&0x7F);
  7. unsigned int mantissa=((unsigned int)byte3<<16)|(byte2<<8)|(byte1);
  8. if(exponent<63)
  9.  return 0.0; // nombres négatifs, impossible dans mon cas
  10. else
  11.  exponent-=63;
  12. exponent*=2; //!!
  13. if((mantissa&(1<<23))==0)
  14. {
  15.  mantissa|=1<<23;
  16.  exponent--;
  17. }
  18. int i;
  19. float f=1;
  20. while(exponent--)
  21.  f*=2;
  22. float val=0;
  23. for(i=23;i>=0;i--)
  24. {
  25.  if(mantissa&(1<<i))
  26.   val+=f;
  27.  f/=2;
  28. }
  29. return (sign)?(-val/10):(val/10);
  30. }
  31. int main(void)
  32. {
  33. printf("0.0->%f\n", decode(0x00, 0x00, 0x00, 0x00));
  34. printf("0.1->%f\n", decode(0x00, 0x00, 0x80, 0x3f));
  35. printf("0.2->%f\n", decode(0x00, 0x00, 0x00, 0x40));
  36. printf("0.3->%f\n", decode(0x00, 0x00, 0x40, 0x40));
  37. printf("0.4->%f\n", decode(0x00, 0x00, 0x80, 0x40));
  38. printf("0.5->%f\n", decode(0x00, 0x00, 0xa0, 0x40));
  39. printf("0.6->%f\n", decode(0x00, 0x00, 0xc0, 0x40));
  40. printf("0.7->%f\n", decode(0x00, 0x00, 0xe0, 0x40));
  41. printf("0.8->%f\n", decode(0x00, 0x00, 0x00, 0x41));
  42. printf("0.9->%f\n", decode(0x00, 0x00, 0x10, 0x41));
  43. printf("1.0->%f\n", decode(0x00, 0x00, 0x20, 0x41));
  44. printf("1.1->%f\n", decode(0x00, 0x00, 0x30, 0x41));
  45. printf("1.2->%f\n", decode(0x00, 0x00, 0x40, 0x41));
  46. printf("1.3->%f\n", decode(0x00, 0x00, 0x50, 0x41));
  47. printf("1.4->%f\n", decode(0x00, 0x00, 0x60, 0x41));
  48. printf("1.5->%f\n", decode(0x00, 0x00, 0x70, 0x41));
  49. printf("2.0->%f\n", decode(0x00, 0x00, 0xa0, 0x41));
  50. printf("3.0->%f\n", decode(0x00, 0x00, 0xf0, 0x41));
  51. printf("3.2->%f\n", decode(0x00, 0x00, 0x00, 0x42));
  52. printf("4.0->%f\n", decode(0x00, 0x00, 0x20, 0x42));
  53. printf("5.0->%f\n", decode(0x00, 0x00, 0x48, 0x42));
  54. printf("6.0->%f\n", decode(0x00, 0x00, 0x70, 0x42));
  55. printf("7.0->%f\n", decode(0x00, 0x00, 0x8c, 0x42));
  56. printf("8.0->%f\n", decode(0x00, 0x00, 0xa0, 0x42));
  57. printf("9.0->%f\n", decode(0x00, 0x00, 0xb4, 0x42));
  58. printf("10.0->%f\n", decode(0x00, 0x00, 0xc8, 0x42));
  59. printf("11.0->%f\n", decode(0x00, 0x00, 0xdc, 0x42));
  60. printf("12.0->%f\n", decode(0x00, 0x00, 0xf0, 0x42));
  61. printf("13.0->%f\n", decode(0x00, 0x00, 0x02, 0x43));
  62. printf("14.0->%f\n", decode(0x00, 0x00, 0x0c, 0x43));
  63. printf("15.0->%f\n", decode(0x00, 0x00, 0x16, 0x43));
  64. printf("16.0->%f\n", decode(0x00, 0x00, 0x20, 0x43));
  65. printf("17.0->%f\n", decode(0x00, 0x00, 0x2a, 0x43));
  66. printf("18.0->%f\n", decode(0x00, 0x00, 0x34, 0x43));
  67. printf("18.1->%f\n", decode(0x00, 0x00, 0x35, 0x43));
  68. printf("18.2->%f\n", decode(0x00, 0x00, 0x36, 0x43));
  69. printf("18.3->%f\n", decode(0x00, 0x00, 0x37, 0x43));
  70. printf("18.4->%f\n", decode(0x00, 0x00, 0x38, 0x43));
  71. printf("18.5->%f\n", decode(0x00, 0x00, 0x39, 0x43));
  72. printf("18.6->%f\n", decode(0x00, 0x00, 0x3a, 0x43));
  73. printf("18.7->%f\n", decode(0x00, 0x00, 0x3b, 0x43));
  74. printf("18.8->%f\n", decode(0x00, 0x00, 0x3c, 0x43));
  75. printf("18.9->%f\n", decode(0x00, 0x00, 0x3d, 0x43));
  76. printf("19.0->%f\n", decode(0x00, 0x00, 0x3e, 0x43));
  77. printf("20.0->%f\n", decode(0x00, 0x00, 0x48, 0x43));
  78. printf("21.0->%f\n", decode(0x00, 0x00, 0x52, 0x43));
  79. printf("22.0->%f\n", decode(0x00, 0x00, 0x5c, 0x43));
  80. printf("25.0->%f\n", decode(0x00, 0x00, 0x7a, 0x43));
  81. printf("30.0->%f\n", decode(0x00, 0x00, 0x96, 0x43));
  82. printf("\n" );
  83. printf("~3,6->%f\n", decode(0x01, 0x00, 0x10, 0x42));
  84. printf("~4,3->%f\n", decode(0x66, 0x66, 0x2A, 0x42));
  85. printf("~6,5->%f\n", decode(0x67, 0x66, 0x82, 0x42));
  86. printf("~9,3->%f\n", decode(0x9A, 0x99, 0xBA, 0x42));
  87. return 0;
  88. }


---------------
Si vous ouvrez un sujet merci de ne pas le "laisser mourir" subitement et de le marquer comme "résolu" le cas échéant!
n°2317814
MaybeEijOr​Not
but someone at least
Posté le 09-07-2018 à 19:09:02  profilanswer
 

Ok, merci.
 
Je jetterai un coup d'oeil mais cette semaine ça va être chaud je pense. :cry:
 
 

Code :
  1. ~3,6  -->  00000001 00000000 00010000 01000010
  2. ~4,3  -->  01100110 01100110 00101010 01000010
  3. ~6,5  -->  01100111 01100110 10000010 01000010
  4. ~9,3  -->  10011010 10011001 10111010 01000010


Message édité par MaybeEijOrNot le 14-07-2018 à 13:34:40

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Divers

  déchiffrer encodage de nombre réels

 

Sujets relatifs
Code jeux du nombre aléatoire en python 3.6Python Qgis et encodage UFT-8
Afficher une suite de nombre avec un char ou int ?Encodage des caractères
Problème d'encodage de liste chainéeImport CSV et encodage en UTF-8
Problème d'encodage ?Limiter le nombre de téléchargement sur mon
Problème encodageEN REXX calculer le nombre de jours ouvrés entre 2 dates
Plus de sujets relatifs à : déchiffrer encodage de nombre réels


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR