質問
誰かが浮動小数点変数に関するバイト順序で私を助けていただけますか?実際のコードでは、Solaris上ではなく、Windows XPで正常に動作しています。ここに私のコードの一部の例です。 ....
int x_snd=1;
float y_snd=1.13;
struct {
int xx_snd;
float yy_snd;
} data_snd;
int x_rec;
float y_rec;
struct {
int xx_rec;
float yy_rec;
} data_rec;
//marshalling
data_snd.xx_snd=htons(x_snd);
data_snd.yy_snd=htonl(*(int*) &y_snd);
//write data to socket
send(sock1, &data_snd, ...
//clean ...
//read data from socket
if recv(sock, &data_rec ...
//unmarshalling
x_rec=ntohs(data_rec.xx_rec);
y_rec= *(float*) &(ntohl(data_rec.yy_rec));
...
ThのコードはwndowsにUnix上gccでとMSVC ++ 6でコンパイルされました。 あなたの助けのいずれかが非常に高く評価されるだろうとあなたは、エンディアン...
に関する便利な情報を提供する任意のリンクまたは文書に私を指示することができれば、私は喜んでいるだろうあなたの助けのためによろしくお願いします、 MK
解決
あなたが整数のマーシャリングとアンマーシャリングするときに対処する必要がちょうどエンディアンの問題よりも、浮動小数点形式でより多くの潜在的な多様性と問題があります。
一つの方法うち、テキストとして浮動小数点数printf
を使用して、そして(bmarguliesが示されているように)strtof()
とそれらを読み戻すフォーマットすることである。
限りマシンが同じFLT_RADIX
値を共有するように動作しますもう一つの方法は、仮数部と指数値にそれらを破ることです。
#include <math.h>
#include <limits.h>
float x = 1.13;
int x_exp;
long x_mant;
x_exp = ilogbf(x);
x_mant = (scalbnf(fabsf(x), -x_exp) - 1) * LONG_MAX;
if (x < 0.0)
x_mant = -x_mant;
あなたは、あなたが行うために、通常のint
とlong
機能を使用することができ、ワイヤ、上に置くx_exp
とx_mant
(上記のコードからntohl()
とhtonl()
)を持っています。 float
、利用されるようにこれらをバックに変換するには:
x = scalbnf((fabsf(x_mant) / LONG_MAX) + 1, x_exp);
if (x_mant < 0)
x = -x;
あなたはコンパイル時にそれをチェックし、それが何か他のものだならば、あなたは合理的に移植する必要があります中止かのように、ほとんどのマシンは、2の(FLT_RADIX
で定義された)float.h
値を持っていることに注意します。
他のヒント
これは一般的に悪い考えです。浮動小数点数の形式であっても、バイトオーダーを考慮した後、必ずしも異なるハードウェア上で同じではありません。私は、文字列としてあちこちでそれらを出荷をお勧めしなければなりません。
両方のシステムが同一の浮動小数点形式を有すると仮定すると、yy_rec
はfloat
あります。 ntohl
はunsigned long
かかります。それはntohl
に渡されるときに浮動小数点値は、潜在的に誤ったエンディアンと、整数表現に変換されます。
あなたが原因float
へunsigned long
から変換するコンパイラの警告を取得する必要があります。