Si vous utilisez Visual C++ faites ce qui suit : Vous incluez intrin.h et appelez les fonctions suivantes :
Pour les nombres de 16 bits :
unsigned short _byteswap_ushort(unsigned short value);
Pour les nombres de 32 bits :
unsigned long _byteswap_ulong(unsigned long value);
Pour les nombres de 64 bits :
unsigned __int64 _byteswap_uint64(unsigned __int64 value);
Les nombres de 8 bits (caractères) n'ont pas besoin d'être convertis.
De plus, ils ne sont définis que pour les valeurs non signées ; ils fonctionnent également pour les entiers signés.
Pour les flottants et les doubles, c'est plus difficile qu'avec les entiers ordinaires, car ils peuvent ou non être dans l'ordre des octets de la machine hôte. Vous pouvez obtenir des flottants little-endian sur des machines big-endian et vice versa.
D'autres compilateurs ont également des intrinsèques similaires.
Sur CCG par exemple, vous pouvez appeler directement quelques builtins comme documenté ici :
uint32_t __builtin_bswap32 (uint32_t x)
uint64_t __builtin_bswap64 (uint64_t x)
(pas besoin d'inclure quelque chose). Je crois que bits.h déclare la même fonction d'une manière non centrée sur gcc.
Un échange de 16 bits, c'est juste une rotation de bits.
En appelant les intrinsèques au lieu de développer les vôtres, vous obtenez les meilleures performances et la meilleure densité de code
0 votes
Avez-vous besoin d'une conversion entre big-endian et little-endian, ou entre l'un de ces formats et votre format natif, pour d'autres traitements ?
0 votes
Il serait utile d'indiquer la plate-forme dont vous parlez.
25 votes
Ntoh hton fonctionnera très bien, même s'il n'a rien à voir avec le réseau.
2 votes
La meilleure façon de gérer l'endianness en général est de s'assurer que le code s'exécute à la fois sur des machines hôtes little- et big-endian. Si cela fonctionne, vous avez probablement bien fait les choses. Supposer que vous êtes sur x86/be est une pratique dangereuse.
13 votes
Hton ntoh ne fonctionnera pas si la machine est big-endian, car l'auteur de la question veut explicitement effectuer la conversion.
6 votes
@jakobengblom2 est la seule personne à l'avoir mentionné. Presque tous les exemples de cette page utilisent des concepts tels que l'échange d'octets au lieu de le faire de manière indépendante de l'endiveté sous-jacente. Si vous traitez avec des formats de fichiers externes (qui ont un endianness bien défini), la chose la plus portable à faire est de traiter les données externes comme un flux d'octets, et de convertir le flux d'octets vers et depuis les entiers natifs. Je frémis chaque fois que je vois
short swap(short x)
car il sera cassé si vous passez à une plateforme avec une endianness différente. Matthieu M a la seule bonne réponse ci-dessous.4 votes
Vous envisagez le problème de manière complètement erronée. La tâche n'est pas "comment puis-je convertir des valeurs big-endian en valeurs little-endian". La tâche est "comment convertir des valeurs entières et à virgule flottante dans un format particulier au format natif de ma plateforme". Si vous le faites correctement, le format natif peut être big endian, little endian, mixed endian ou ternaire, pour le plus grand bien de votre code.
0 votes
Htons est host-to-network-short.