float
sをビッグエンディアンからリトルエンディアンに変換することはできますか? TCPを介してWindowsプロセス(リトルエンディアン)に送信しているPowerPCプラットフォームからのビッグエンディアン値があります。この値はfloat
ですが、memcpy
値をWin32 float型にしてから、その値に_byteswap_ulong
onを呼び出します。常に0.0000を取得しますか?
何が悪いのですか?
単純に4バイトを逆にする
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;
}
データを直接float型に変換しないでください。 charデータとして保持し、バイトを交換して、次に浮動小数点数として扱います。
Ntoaと関連する機能を使用して、ネットワークからホストへ、およびホストからネットワークへ変換する方が簡単かもしれません。 ここ は、これを行う方法を説明する記事へのリンクです。
この値は浮動小数点ですが、値をwin32浮動小数点型に "memcpy"し、その値に対して
_byteswap_ulong
を呼び出すと、常に0.0000を取得しますか?
これは動作するはずです。あなたが持っているコードを投稿できますか?
ただし、パフォーマンスを重視する場合は(おそらくそうしない場合は、残りを無視できます)、memcpyをターゲットの場所に直接ロードしてバイトをスワップするか、スワップを使用することで回避できます。コピー中にスワッピングを行います。
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;
}