3

受信すると、の配列を形成するバイトのストリームを解析していますuint8。配列の内容は、整数、文字列、または浮動小数点数のいずれかであることが事前にわかっています。必要なのは、データをそれらのタイプに再解釈することだけです。しかし、フロートは私にいくつかの懸念を引き起こしています。

私の質問ですが、次の構造は驚くことなく期待どおりに機能しますか?(メモリエイリアシング、パディング、エンディアンなど)そして、そうでない場合、合理的な限り少ないコードでこれを達成するための最良の方法は何でしょうか?

union BytesToFloat{
    float f;
    uint8 bytes[4];
}

背景として、このデータはセーブデータに由来するため、データを書き込むコンピューターが、データを読み取るコンピューターと同じではない可能性があります。

編集

エンディアンに関するコメントの1つを読んだ後、この構造と支援機能がより適切であるか、それともエンディアンが問題のままであるか(またはそれ以上に厄介なことがある可能性があります)

union IntToFloat{
    float f;
    uint32 i;
};

uint32 CharToLong(unsigned char * c){
    uint32 val = c[0];
    val <<= 8;
    val |= c[1];
    val <<= 8;
    val |= c[2]; 
    val <<= 8;
    val |= c[3];
    return val;
}
4

2 に答える 2

1

を に置き換えることで、 union(実際よりも理論的に)の信頼性をわずかに向上させることができます。4sizeof(float)

ただし、ネットワークを介して他の問題に直面する必要があります。接続の両端で IEEE 754 浮動小数点形式 (たとえば、IBM の zSeries メインフレーム) が使用されるという保証はありません。また、両側が同じバイト順を使用するという保証もありません (Intel アーキテクチャはリトル エンディアンを使用し、他のほとんどのアーキテクチャはビッグ エンディアンを使用します)。データを正しく解釈するには、送信元コンピューターと送信先コンピューターのバイト順を知る必要があります (ただし、IBM が SQL DBMS との通信に使用する DRDA プロトコルは、「受信者が正しくする」という規則に従って、そのように機能します)。

エンディアンとバイト順の問題は実用的な問題です。メインフレーム システムで遊ぶ予定がない限り、浮動小数点形式はあまり問題にならない傾向があります (IEEE 754 が標準化される前にその形式が確立されたため、IEEE 754 のホールドアウトになる傾向があります)。

多くの場合、データを送信する最善の方法は、プレーンテキスト形式を使用することです。これには、デバッグが容易で、数値表現の難しい問題の多く (すべてではない) を回避できるという利点があります。ただし、プライマリ プロトコルがバイナリの場合、浮動小数点のテキストに変更するのは奇妙に見えます。

于 2013-01-27T01:54:05.593 に答える
0

はい、驚きがあります。両端で。

そのコードがどのように機能するかは、読み取りと書き込みの両方で定義された実装になります。

プラス面として、多くの場合、トランスポートメディア(ネットワークまたはディスク)は非常に遅いため、読み取り/書き込みを決定論的にするためのコードを追加しても、パフォーマンスに大きな影響はありません。

もう1つの良い点は、コードを任意のプラットフォームで実行する必要がほとんどないことです。あなたがしていることがあなたがサポートする各プラットフォームで機能し、あなたが良いことを確認してください。

于 2013-01-26T10:18:35.087 に答える