web-dev-qa-db-ja.com

浮動小数点値をビッグエンディアンからリトルエンディアンに変換する

floatsをビッグエンディアンからリトルエンディアンに変換することはできますか? TCPを介してWindowsプロセス(リトルエンディアン)に送信しているPowerPCプラットフォームからのビッグエンディアン値があります。この値はfloatですが、memcpy値をWin32 float型にしてから、その値に_byteswap_ulongonを呼び出します。常に0.0000を取得しますか?

何が悪いのですか?

19
Blade3

単純に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;
}
30
Gregor Brandt

ずいぶん昔にこんな感じで見つけました。 には良かったのですが、自分の危険を冒してください。私もそれをコンパイルしていません:

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

以下は、任意のタイプのバイト順を逆にすることができる関数です。

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

データを直接float型に変換しないでください。 charデータとして保持し、バイトを交換して、次に浮動小数点数として扱います。

2
jscharf

Ntoaと関連する機能を使用して、ネットワークからホストへ、およびホストからネットワークへ変換する方が簡単かもしれません。 ここ は、これを行う方法を説明する記事へのリンクです。

1
t0mm13b

この値は浮動小数点ですが、値をwin32浮動小数点型に "memcpy"し、その値に対して_byteswap_ulongを呼び出すと、常に0.0000を取得しますか?

これは動作するはずです。あなたが持っているコードを投稿できますか?

ただし、パフォーマンスを重視する場合は(おそらくそうしない場合は、残りを無視できます)、memcpyをターゲットの場所に直接ロードしてバイトをスワップするか、スワップを使用することで回避できます。コピー中にスワッピングを行います。

0
Suma

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