Преобразование значений с плавающей точкой от большого 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,)