C de la Fonction de Convertir flotteur de tableau d'octets
Je suis en train de faire une fonction qui va accepter une variable de type float et de le convertir en un tableau d'octets. J'ai trouvé un bout de code qui fonctionne, mais souhaitez réutiliser dans une fonction si possible.
Je travaille aussi avec l'environnement Arduino, mais je comprends qu'il accepte la plupart des langage C.
Actuellement fonctionne:
float_variable = 1.11;
byte bytes_array[4];
*((float *)bytes_array) = float_variable;
Que puis-je modifier pour que cela fonctionne?
float float_test = 1.11;
byte bytes[4];
//Calling the function
float2Bytes(&bytes,float_test);
//Function
void float2Bytes(byte* bytes_temp[4],float float_variable){
*(float*)bytes_temp = float_variable;
}
Je ne suis pas familier avec les pointeurs et, mais j'ai lu que (float) est à l'aide de moulage ou de quelque chose?
Toute aide serait grandement appréciée!
Acclamations
*EDIT: RÉSOLU
Voici ma dernière fonction qui fonctionne dans l'Arduino pour toute personne qui le trouve. Il y a des solutions plus efficaces dans les réponses ci-dessous, cependant, je pense que c'est ok pour comprendre.
Fonction: convertit entrée variable de type float de tableau d'octets
void float2Bytes(float val,byte* bytes_array){
//Create union of shared memory space
union {
float float_variable;
byte temp_array[4];
} u;
//Overite bytes of union with float variable
u.float_variable = val;
//Assign bytes to input array
memcpy(bytes_array, u.temp_array, 4);
}
Appel de la fonction
float float_example = 1.11;
byte bytes[4];
float2Bytes(float_example,&bytes[0]);
Merci pour l'aide de tous, j'ai beaucoup appris sur les pointeurs et le référencement dans les 20 dernières minutes, les Acclamations de Débordement de Pile!
OriginalL'auteur Ben Winding | 2014-06-25
Vous devez vous connecter pour publier un commentaire.
Plus simple est de faire une union:
De sortie:
Remarque - il n'y a aucune garantie quant à l'ordre des octets... cela dépend de votre architecture de la machine.
Pour obtenir votre fonction, ce faire:
Ou vraiment hack:
Remarque - dans les deux cas, j'ai assurez-vous de copier les données à l'emplacement donné que le paramètre d'entrée. Cela est essentiel, car les variables locales n'existent pas après votre retour (même si vous pourriez déclarer
static
, mais n'allons pas vous apprendre de mauvaises habitudes. Si la fonction est appelée de nouveau...)l'union de deux éléments de données de quatre octets la taille qui rend ces deux occupent la même mémoire physique - donc, quand j'écris à
thing.a
j'écris dans le tableau d'octets. Vous trouverez que&thing.a == &thing.bytes
...Ay, a obtenu. Je suis de rire de mon auto maintenant........! Mais vraiment bon. +1
Merci beaucoup! Je suis enfin de comprendre le concept de syndicats
J'ai été un peu surpris de votre question, et compte tenu de la qualité de vos contributions autour d'ici, en fait me suis interrogé ("ai-je fait quelque chose de vraiment stupide? S'ils n'ont pas compilé?" J'ai même tourné sur
-Wstrict-aliasing
la recherche de problèmes...). Merci pour le +.OriginalL'auteur Floris
Voici une façon de faire ce que vous voulez qui ne cassera pas si vous êtes sur un système par un autre endianness de celui que vous êtes maintenant sur:
Vous pouvez le voir en action ici: http://ideone.com/umY1bB
Le problème avec les réponses ci-dessus, c'est qu'ils s'appuient sur la représentation sous-jacente de
float
s: C ne garantit pas que l'octet le plus significatif sera la "première" dans la mémoire. La norme permet au système sous-jacent à mettre en œuvrefloat
s cependant, il se sent comme -- donc, si vous tester votre code sur un système avec un type particulier de l'endianness (ordre des octets pour les types numériques dans la mémoire), il cessera de fonctionner selon le type de processeur que vous êtes en cours d'exécution sur.C'est vraiment un méchant, dur-à-correction d'un bug et vous devriez l'éviter si possible.
Il fonctionne sur les systèmes, car il n'est pas "casser" la notion d'un flotteur que le système fonctionne. À l'aide d'une union interagit directement avec les valeurs en mémoire, donc cela dépend si le système stocke l'octet le plus significatif dans la plus haute octet de poids du flotteur. L'utilisation de cette stratégie passe seulement par d'autres abstractions --
int
et bitshifting -- de sorte qu'il sera cohérente, peu importe la façon dont le système sous-jacent, les ordres de ses octets.Le bit le plus significatif d'un
float
et unint
sera dans le même lieu, indépendamment de l'endianness -- bitshifting de masquage et va sortir correctement. Toutefois, le système ne garantit pas que le bit le plus significatif d'unfloat
est le plus élevé-de l'ordre de bits, de sorte que peut se briser si vous utilisez ununion
sur un système de différentes boutisme de celui que vous avez développé.Il n'a pas à faire avec "la mauvaise interprétation d'un flotteur," plutôt, certains systèmes de représenter les nombres en tant que [MOST_SIGNIFICANT_BYTE, 2ND_MOST_SIGNIFICANT, 2ND_LEAST_SIGNIFICANT, LEAST_SIGNIFICANT] et d'autres de les représenter en tant que [LEAST_SIGNIFICANT, 2ND_LEAST_SIGNIFICANT, 2ND_MOST_SIGNIFICANT, MOST_SIGNIFICANT].
Ahh je crois que je vois, il compare le premier nombre de bits significatifs à l'aide de bits de masquage, pour un autre type int ou float à assurez-vous que les octets sont dans le bon ordre. C'est cette sorte de droit?
OriginalL'auteur Patrick Collins
Je voudrais vous recommandons d'essayer une "union".
Regarder ce post:
http://forum.arduino.cc/index.php?topic=158911.0
Dans votre cas, quelque chose comme:
OriginalL'auteur FoggyDay
Encore une autre façon, sans les syndicats:
(En supposant que l'octet = unsigned char)
Suis-je une erreur de lecture? Selon le lien: Un objet doit avoir sa valeur stockée et accessible uniquement par une lvalue expression qui est l'un des types suivants qui inclut un type de caractère.
Merci. Il était très curieux, que j'ai trouvé ce petit hack pour être utile dans plusieurs situations, mais n'avait pas eu quelque chose de blow up.
Bien, bon à savoir, de toute façon, depuis que je suis probablement un peu trop généreux avec mes typecasting 🙂
De même, j'ai appris quelque chose aujourd'hui. J'ai supprimé mes commentaires ci-dessus maintenant, depuis qu'ils sont juste du bruit et de ne pas contribuer quoi que ce soit. Un vote...
OriginalL'auteur Christopher Schneider
Bien que les autres réponses montrent comment accomplir cela en utilisant un syndicat, vous pouvez l'utiliser pour mettre en œuvre la fonction que vous voulez comme ceci:
ou
u
n'existent pas. Vous pouvez allouer dynamiquement de l'union à son pointeur:my_union *u = malloc(sizeof(my_union));
.C'est un peu plus l'habitude d'écrire
u->float_variable
plutôt que(*u).float_variable
, n'est-ce pas? Aucune raison particulière pour laquelle vous avez choisi de cette façon? Notons également que, dans la question, la signature de la fonction adopté le pointeur vers le résultat en tant que paramètre.De travail du téléphone. Était trop paresseux pour trouver l' > personnage. Fixe maintenant.
OriginalL'auteur mclaassen
cela semble fonctionner aussi
puis
aussi pour le double
puis
OriginalL'auteur Enzo Guerra