Преобразование значений float из big endian в little endian

можно ли преобразовать floats от большого к маленькому эндиану? У меня есть большое значение endian от платформы PowerPC, которую я отправляю через TCP в процесс Windows (little endian). Это значение является float, но, когда я memcpy значение в тип Win32 float, а затем вызовите _byteswap_ulongна этом значении я всегда получаю 0.0000?

что я делаю не так?

7 ответов


просто обратный четыре байта работает

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;
}

Я нашел что-то примерно так давно. Это было хорошо для смех, но принимать на свой страх и риск. Я даже не составил его:

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;
}

здесь функция может изменить порядок байтов любого типа.

template <typename T>
T bswap(T val) {
    T retVal;
    char *pVal = (char*) &val;
    char *pRetVal = (char*)&retVal;
    int size = sizeof(T);
    for(int i=0; i<size; i++) {
        pRetVal[size-1-i] = pVal[i];
    }

    return retVal;
}

не memcpy данные непосредственно в тип float. Держите его как char данные, поменять местами байты и затем рассматривать его как поплавок.


возможно, проще использовать ntoa и связанные с ним функции для преобразования из сети в хост и из хоста в сеть..преимущество было бы портативным. здесь - это ссылка на статью, в которой объясняется, как это сделать.


это значение является float, но когда я "memcpy" значение в тип Win32 float, а затем вызовите _byteswap_ulong на этом значении я всегда получаю 0.0000?

Это должно работать. Можете ли вы опубликовать код, который у вас есть?

однако, если вы заботитесь о производительности (возможно, вы этого не делаете, в этом случае вы можете игнорировать остальное), должно быть возможно избежать memcpy, либо напрямую загрузив его в целевое местоположение и поменяв там байты, либо используя своп, который делает обмен при копировании.


хороший способ добраться до значения-использовать struct.упаковать / распаковать.
Вы можете использовать символ " > " в формате, чтобы указать, что байты находятся в обратном направлении (big endian).

from struct import unpack, pack
sebytes = '\xc8\x00\x00\x00'
print unpack('l', sebytes)
bebytes = '\x00\x00\x00\xc8'
print unpack('>l', bebytes)

выход:

(200,)
(200,)