Преобразование значений с плавающей точкой от большого endian до little endian

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

Что я делаю неправильно?

Ответ 1

просто отмените работу с четырьмя байтами

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

Не memcpy данные непосредственно в тип float. Храните его как char, поменяйте байты и обработайте его как float.

Ответ 6

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

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

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

Ответ 7

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

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,)