C++ 将浮点值从大端转换为小端
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2782725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting float values from big endian to little endian
提问by Blade3
Is it possible to convert float
s from big to little endian? I have a big endian value from a PowerPC platform that I am sendING via TCP to a Windows process (little endian). This value is a float
, but when I memcpy
the value into a Win32 float type and then call _byteswap_ulong
on that value, I always get 0.0000?
是否可以将float
s 从大端转换为小端?我有一个来自 PowerPC 平台的大端值,我通过 TCP 发送到 Windows 进程(小端)。这个值是 a float
,但是当我memcpy
将该值转换为 Win32 浮点类型然后调用_byteswap_ulong
该值时,我总是得到 0.0000?
What am I doing wrong?
我究竟做错了什么?
回答by Gregor Brandt
simply reverse the four bytes works
只需反转四个字节即可
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;
}
回答by Sniggerfardimungus
I found something roughly like this a long time ago. It was good for a laugh, but ingest at your own peril. I've not even compiled it:
很久以前我发现了大致类似的东西。这很好笑,但要自担风险。我什至没有编译它:
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;
}
回答by Benjamin
Here is a function can reverse byte order of any type.
这是一个可以反转任何类型字节顺序的函数。
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;
}
回答by jscharf
Don't memcpy the data directly into a float type. Keep it as chardata, swap the bytes and thentreat it as a float.
不要将数据直接存储为浮点类型。将其保留为字符数据,交换字节,然后将其视为浮点数。
回答by Antonio Ca?as Vargas
An elegant way to do the byte exchange is to use a union:
进行字节交换的一种优雅方式是使用联合:
float big2little (float f)
{
union
{
float f;
char b[4];
} src, dst;
src.f = f;
dst.b[3] = src.b[0];
dst.b[2] = src.b[1];
dst.b[1] = src.b[2];
dst.b[0] = src.b[3];
return dst.f;
}
Following jjmerelo's recommendation to write a loop, a more generic solution could be:
按照 jjmerelo 编写循环的建议,更通用的解决方案可能是:
typedef float number_t;
#define NUMBER_SIZE sizeof(number_t)
number_t big2little (number_t n)
{
union
{
number_t n;
char b[NUMBER_SIZE];
} src, dst;
src.n = n;
for (size_t i=0; i<NUMBER_SIZE; i++)
dst.b[i] = src.b[NUMBER_SIZE-1 - i];
return dst.n;
}
回答by t0mm13b
回答by infval
From SDL_endian.hwith slight changes:
从SDL_endian.h略有变化:
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;
}
回答by Suma
This value is a float, but when I "memcpy" the value into a win32 float type and then call
_byteswap_ulong
on that value, I always get 0.0000?
这个值是一个浮点数,但是当我将这个值“memcpy”成一个 win32 浮点类型然后调用
_byteswap_ulong
那个值时,我总是得到 0.0000?
This should work. Can you post the code you have?
这应该有效。你能把你的代码贴出来吗?
However, if you care for performance (perhaps you do not, in that case you can ignore the rest), it should be possible to avoid memcpy, either by directly loading it into the target location and swapping the bytes there, or using a swap which does the swapping while copying.
但是,如果您关心性能(也许您不关心,在这种情况下您可以忽略其余部分),应该可以避免 memcpy,方法是将其直接加载到目标位置并在那里交换字节,或者使用交换它在复制时进行交换。
回答by steppenwolf
A nice way to get to the value is to use struct.pack/unpack.
You can use the ">" character in the format to indicate that the bytes are in reverse (big endian).
获取值的一个好方法是使用 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)
output:
输出:
(200,)
(200,)