web-dev-qa-db-fra.com

Conversion des valeurs de flotteur de Big Endian au petit Endian

Est-il possible de convertir float S du grand à la petite Endian? J'ai une grande valeur Endian à partir d'une plate-forme PowerPC que j'envoie via TCP à un processus Windows (petit Endian). Cette valeur est un float, mais quand je memcpy la valeur dans un type de flotteur Win32 puis appelez _byteswap_ulongon cette valeur, j'ai toujours 0.0000?

Qu'est-ce que je fais mal?

19
Blade3

simplement inverser les quatre octets fonctionne

float ReverseFloat( const float inFloat )
{
   float retVal;
   char *floatToConvert = ( char* ) & inFloat;
   char *returnFloat = ( char* ) & retVal;

   // swap the bytes into a temporary buffer
   returnFloat[0] = floatToConvert[3];
   returnFloat[1] = floatToConvert[2];
   returnFloat[2] = floatToConvert[1];
   returnFloat[3] = floatToConvert[0];

   return retVal;
}
30
Gregor Brandt

J'ai trouvé quelque chose d'approximativement comme celui-ci il y a longtemps. C'était bon pour un rire, mais ingérer à votre propre péril. Je ne l'ai même pas compilé:

void * endian_swap(void * arg)
{
    unsigned int n = *((int*)arg);
    n = ((n >>  8) & 0x00ff00ff) | ((n <<  8) & 0xff00ff00);
    n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
    *arg = n;   

    return arg;
}
7

Ne pas mémoriser les données directement dans un type de flotteur. Gardez-le comme char Données, échangez les octets et alors Traitez-le comme un flotteur.

2
jscharf

Il pourrait être plus facile d'utiliser l'ONTO et les fonctions associées pour convertir du réseau à l'hôte et à l'hôte au réseau .. L'avantage serait portable. ICI est un lien vers un article qui explique comment faire cela.

1
t0mm13b

Cette valeur est un flotteur, mais lorsque je "memcpy" la valeur dans un type de flotteur Win32 puis appelle _byteswap_ulong sur cette valeur, j'ai toujours 0.0000?

Cela devrait fonctionner. Pouvez-vous poster le code que vous avez?

Cependant, si vous vous souciez de performances (peut-être que vous ne le faites pas, dans ce cas, vous pouvez ignorer le reste), il devrait être possible d'éviter le memcpy, soit en le charger directement dans l'emplacement cible et d'échanger les octets là-bas, soit à l'aide d'un swap. qui fait l'échange lors de la copie.

0
Suma

De - sdl_endian.h avec de légers changements:

std::uint32_t Swap32(std::uint32_t x)
{
    return static_cast<std::uint32_t>((x << 24) | ((x << 8) & 0x00FF0000) |
                                      ((x >> 8) & 0x0000FF00) | (x >> 24));
}

float SwapFloat(float x)
{
    union
    {
        float f;
        std::uint32_t ui32;
    } swapper;
    swapper.f = x;
    swapper.ui32 = Swap32(swapper.ui32);
    return swapper.f;
}
0
infval