Преобразование значений float из big endian в little endian
можно ли преобразовать float
s от большого к маленькому эндиану? У меня есть большое значение 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,)