|
Publicité ' | ||||||||||||||||||||||
|
|
#1 |
|
Invité de passage
![]() Inscription : septembre 2008 Messages : 4 ![]() |
Bonjour,
Je travaille sur un projet sur un PIC18f4550 sous MPLAB avec un compilateur C18. Je recois 4 octets de type char. Je voudrais recopier (bit a bit car les 4 octets char sont déjà au format float : 1 bit de signe + 8 bits d'exposant + 23 bit de valeurs) ces 4 octets char dans un float. Je n'arrive à rien de bon car j'ai un niveau basique en C. J'ai vraiment besoin d'un coup de main svp. Merci d'avance. |
|
|
00
|
|
|
#2 | |||||
|
Expert Confirmé Sénior
![]() ![]() Frédéric Ingénieur développement logiciels Inscription : février 2006 Messages : 3 495 ![]() |
Citation:
Code c :
Ou bien utiliser une union (qui a tous ces membres au même emplacement mémoire) Code c :
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche. Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit. Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant. Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation. Dr. Adrian Rogers, 1931 |
|||||
|
|
00
|
|
|
#3 | ||
![]() ![]() Patrick GonordEnseignant Chercheur Inscription : juin 2005 Messages : 5 434 ![]() |
@Sve@r :
La première méthode ne peut pas marcher : Code :
f=(a << 24) | (b << 16) | (c << 8) | d; Une alternative à la seconde méthode : Code :
__________________
Publication : Concepts en C Mon avatar : Glenn Gould -------------------------------------------------------------------------- Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
|
||
|
|
20
|
|
|
#4 | ||||
|
Expert Confirmé Sénior
![]() ![]() Frédéric Ingénieur développement logiciels Inscription : février 2006 Messages : 3 495 ![]() |
Citation:
Citation:
L'opération int u=... va recoder tous les octets a, b, c et d dans le format int avec risque de mélange des bits selon le codage little-endian/big-endian. Puis le contenu de l'adresse prise comme adresse de float sera claqué dans le float mais ce sera trop tard. On aura déjà perdu le codage intrinsèque d'un float (mantisse, exposant etc...) Et même si par miracle on le garde, ce ne sera ni pérenne (le codage float peut ensuite changer) ni portable. La solution union fonctionne. Et à mon avis c'est la seule possible.
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche. Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit. Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant. Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation. Dr. Adrian Rogers, 1931 |
||||
|
|
00
|
|
|
#5 | |
![]() ![]() Patrick GonordEnseignant Chercheur Inscription : juin 2005 Messages : 5 434 ![]() |
Citation:
Dans cette opération, la représentation binaire de f sera celle de u. Evidemment, il faut qu'on ait reconstitué correctement la représentation binaire du float (que ce soit dans l'unsigned int u ou dans le tableau tab de l'union); cette reconstitution correcte est une obligation quelle que soit la méthode utilisée. Evidemment, cette étape de reconstitution ne pourra jamais être portable et dépend du codage des float. Sinon, les deux méthodes pour passer de la représentation binaire stockée dans un entier ou dans un tableau de char en la valeur d'un float sont fondamentalement identique : Dans le cas de l'union, elle est basée sur le fait que, grace à l'union, l'adresse de départ du tableau est (implicitement) l'adresse du float ; dans le cas de l'unsigned int, on dit (explicitement) que l'adresse de l'unsigned int est l'adresse d'un float.
__________________
Publication : Concepts en C Mon avatar : Glenn Gould -------------------------------------------------------------------------- Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
|
|
|
|
10
|
|
|
#6 | ||
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Et les deux méthodes sont des comportement indéfinis. Variantes qui ne peuvent l'être que pour des raisons de représentation:
Code :
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
||
|
|
10
|
|
|
#7 | |||
|
Expert Confirmé Sénior
![]() ![]() Frédéric Ingénieur développement logiciels Inscription : février 2006 Messages : 3 495 ![]() |
Citation:
Là je ne pige pas trop. Bon, la solution mix des bits me semble en effet très aléatoire. Mais la solution union me semble correcte non ? (dans l'hypothèse évidente où a, b, c et d sont super bien formatés quoi)...
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche. Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit. Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant. Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation. Dr. Adrian Rogers, 1931 |
|||
|
|
00
|
|
|
#8 |
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Lire autre chose que le dernier champs écrit d'une union est un comportement indéfini. Le type prunning aussi (en gros même chose que pour les unions: on ne peut lire que le dernier type écrit -- sauf qu'on peut lire/écrire des chars). Le risque n'est pas tant un comportement bizarre de l'architecture que l'intervention des optimiseurs qui utilisent ces interdictions pour éviter de recharger des choses dans les registres... Comme ces techniques sont quand même d'un usage assez courant, certains essayent de les détecter et d'agir comme désiré, mais si c'est un peu trop subtil pour le code de détection, c'est fichu.
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
|
|
20
|
|
|
#9 | |
|
Expert Confirmé Sénior
![]() ![]() Frédéric Ingénieur développement logiciels Inscription : février 2006 Messages : 3 495 ![]() |
Citation:
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche. Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit. Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant. Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation. Dr. Adrian Rogers, 1931 |
|
|
|
00
|
|
|
#10 |
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Si tu veux, il y a plus sur ce sujet...
Si le dernier membre ecrit est une structure et qu'il y a d'autres structures dans l'union partageant une sequence initiale de membres, on peut lire cette sequence initiale a travers ces autres structures. Et puis je remarque qu'on est en C et pas en C++. En C89, lire un autre membre que le dernier ecrit est un comportement defini par l'implementation, pas indefini. En C99, les bytes autres que les derniers ecrits sont indefinis, mais la partie partagee avec le dernier membre ecrit est reinterpretee. Donc le cas present est l'utilisation de l'union a un comportement indefini en C++, defini par l'implementation en C89 et equivalent au memcpy en C99. Sauf erreur de ma part, c'est un peu tordu ce machin. (L'utilisation de pointeurs est inedefini dans tous les cas et memcpy fait ce qui est desire dans tous les cas, ca me semble toujours la solution la plus simple).
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
|
|
10
|
|
|
#11 | ||
![]() ![]() Patrick GonordEnseignant Chercheur Inscription : juin 2005 Messages : 5 434 ![]() |
@Jean-Marc
Puisqu'on est sur le sujet des transtypages de pointeurs, peux-tu me dire si ces 8 propositions te semblent correctes ? En notant : - collectivement Tchar l'un des types char, unsigned char et signed char - TX et TY deux types différents et différents d'un Tchar et de void : 1- TX * -> TY * : comportement indéfini si TY peut n'être pas aligné sur l'alignement de TX. 2- Tchar * -> TX * : comportement indéfini si TX peut n'être pas aligné sur l'alignement de Tchar. 3- TX * -> Tchar * : valide 4- TX * -> Tchar * -> TX * : valide 5- TX * -> Tchar * -> TY * : comportement indéfini si TY peut n'être pas aligné sur l'alignement de TX. 6- TX * -> void * : valide 7- TX * -> void * -> TX * : valide 8- TX * -> void * -> TY * : comportement indéfini si TY peut n'être pas aligné sur l'alignement de TX. Sans remettre en cause les autres solutions apportées, ceci devrait alors être correct : Code :
__________________
Publication : Concepts en C Mon avatar : Glenn Gould -------------------------------------------------------------------------- Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
|
||
|
|
00
|
|
|
#12 | ||||
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Citation:
Citation:
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
||||
|
|
20
|
|
|
#13 |
![]() ![]() Patrick GonordEnseignant Chercheur Inscription : juin 2005 Messages : 5 434 ![]() |
@Jean-Marc
Merci pour toutes ces précisions.
__________________
Publication : Concepts en C Mon avatar : Glenn Gould -------------------------------------------------------------------------- Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
|
|
|
00
|
|
|
#14 | ||||
|
Membre habitué
![]() Martin BousquetDéveloppeur de jeux vidéo Inscription : octobre 2008 Messages : 93 ![]() |
Dans le même genre, en considérant l'union suivante :
Code :
Code :
|
||||
|
|
00
|
|
|
#15 | |||||
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Citation:
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
|||||
|
|
10
|
Copyright © 2000-2013 - www.developpez.com