12
votes

Obtenir des mots 32 bits sur des valeurs de 64 bits en C / C ++ et ne vous inquiétez pas de l'endansion

C'est à ma compréhension que les opérateurs bitwises C / C ++ sont censés être indépendants de Endian et se comporteront de la façon dont vous vous attendez. Je veux m'assurer que je reçois vraiment les mots les plus significatifs et les moins importants d'une valeur de 64 bits et ne vous inquiétez pas de l'endansion de la machine. Voici un exemple:

uint64_t temp;
uint32_t msw, lsw;
msw = (temp & 0xFFFFFFFF00000000) >> 32;
lsw = temp & 0x00000000FFFFFFFF;


8 Réponses :


2
votes

Oui. Cela devrait fonctionner.


0 commentaires

17
votes

6.5.7 Opérateurs de décalage bit-bit

4 Le résultat de E1 << E2 est E1 positions de bits E2 décalés de gauche; vacant Les bits sont remplis de zéros. Si e1 a un type non signé, la valeur du Le résultat est E1 × 2e2, réduit modulo un plus que la valeur maximale représentable dans le type de résultat. Si E1 a un type signé et non négatif La valeur et e1 × 2e2 sont représentables dans le type de résultat, c'est alors le valeur résultante; Sinon, le le comportement est indéfini.

Alors, oui - Guranteed par la norme.


0 commentaires

0
votes

Je pense que ce que vous dites est tout à fait vrai, mais où cela vous a-t-il?

Si vous avez des valeurs littérales suspendues, vous savez quelle fin est la fin. Mais si vous vous trouvez avec des valeurs provenant de l'extérieur du programme, vous ne pouvez pas être sûr, à moins qu'elles n'aient pas été codées d'une manière ou d'une autre.


0 commentaires

3
votes

Oui, cela devrait fonctionner. Lorsque vous récupérez le MSW, votre masque n'aboutit pas vraiment bien mais les bits que vous masquez à zéro seront jetés lorsque vous faites le quart de temps. Personnellement, j'utiliserais probablement quelque chose comme ceci: xxx

bien sûr, pour produire un résultat significatif, Temp doit être initialisé, ce qu'il n'était pas dans votre code.


3 commentaires

Oui, je n'étais pas préoccupé par la valeur de Temp pour cette affaire, juste une vérification de la santé mentale que je reçois réellement le MSW et la LSW.


Qu'est-ce que & = est ici cette affectation ordinaire ne serait-elle pas?


@ROB: Tant que la destination est exactement la taille de sortie souhaitée, cela n'aboutit rien. Si, toutefois, vous vouliez quelque chose comme les 24 bits inférieurs, et deviez le mettre dans un type de 32 bits, alors vous auriez besoin de la masquer.



1
votes

Une pensée que je voudrais partager, peut-être que vous pourriez peut-être contourner l'endanianesse d'une valeur en utilisant les fonctions ou les macros trouvées dans , pour convertir le réseau à Ordre de l'hôte et vice versa, on peut dire qu'il est plus utilisé conjointement avec des sockets, mais il pourrait être utilisé pour cette instance afin de garantir une valeur telle que 0xabcd d'un autre processeur est toujours 0xabcd sur Intel X86, au lieu de recourir à Fonctions personnalisées codées à la main pour faire face à l'architecture d'Endian ....!

EDIT: Voici un article sur Endianess sur CodeProject < / a> et l'auteur a développé des macros pour traiter des valeurs de 64 bits.

J'espère que cela aide, Meilleures salutations, Tom.


1 commentaires

Cela ne me semble pas que l'affiche se soucie de l'endansion, mais plutôt de 64 bits dans la plupart des plus significatifs et les moins significatifs 32. Vraisemblablement les entiers 32 bits auront la même endansité que les entiers 64 bits.



0
votes

En plus des autres réponses, j'ajouterai que vous ne devriez pas vous inquiéter de l'endansité dans C. Endianness Problème vient uniquement de regarder certains octets sous un type différent de celui utilisé pour écrire ces octets en premier lieu. Lorsque vous faites cela, vous êtes très proche d'avoir des problèmes d'aliasing, ce qui signifie que votre code peut casser lors de l'utilisation d'un autre compilateur ou d'un autre drapeau d'optimisation.

Tant que vous n'essayez pas de faire de tels accès de type trans, votre code doit être neutre de l'Endian et s'exécuter parfaitement sur les architectures de petites-Endian et de grande endian. Ou, autrement dit, si vous avez des problèmes d'endansement, les autres types de problèmes plus importants se cachent également à proximité.


0 commentaires

5
votes

Cela fonctionnera, mais la propension étrange de certains auteurs pour faire un bit-masquing avant que le changement de bit-shifting me perlaisse toujours.

À mon avis, une approche beaucoup plus élégante serait celle qui fait le changement d'abord xxx

au moins parce qu'il utilise la même constante de masque bit "magique" à chaque fois.

Maintenant, si votre type cible est non signé et que la largeur de bits souhaitée, le masquage devient complètement non spécifique xxx


1 commentaires

Wow, je suis heureux au moins on mentionné le faire de cette façon! +1 pour la cohérence dans le bit-masque :)



1
votes

Endianness concerne la mise en page de la mémoire. Le changement est sur les bits (et la mise en page de bit). La signification de mot concerne la mise en page de bit, pas la mise en page de la mémoire. Donc, l'endianness n'a rien à voir avec la signification des mots.


0 commentaires