0

有人可以帮我处理浮点变量的字节顺序吗?实际上,代码在 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));

...

代码在 Unix 上用 gcc 编译,在 wndows 上用 MSVC++6 编译。您的任何帮助将不胜感激,如果您能指导我访问任何提供有关字节序的有用信息的链接或文档,我将很高兴...

提前感谢您的帮助,mk

4

3 回答 3

2

这是一个普遍的坏主意。即使在考虑字节顺序之后,浮点数的格式在不同的硬件上也不一定相同。我不得不建议将它们作为字符串运送到这里和那里。

于 2009-11-11T23:44:56.983 回答
2

浮点格式的潜在多样性和问题不仅仅是在编组和解组整数时必须处理的字节序问题。

一种出路是将浮点数格式化为文本,使用,并用(如 bmargulies 所示)printf读回它们。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和一个longx_expx_mant来自上面的代码)放在电线上,你可以使用正常的ntohl()htonl()功能来做。要将它们转换回float,请使用:

x = scalbnf((fabsf(x_mant) / LONG_MAX) + 1, x_exp);
if (x_mant < 0)
    x = -x;

请注意,大多数机器的FLT_RADIX值(在 中定义float.h)为 2,因此,如果您在编译期间检查该值并中止它,如果它是其他东西,那么您应该是相当可移植的。

于 2009-11-12T00:26:21.147 回答
1

假设两个系统具有相同的浮点格式,yy_rec是 a float; ntohl需要一个unsigned long;浮点值(可能具有不正确的字节顺序)在传递到ntohl.

float由于从到的转换,您应该收到编译器警告unsigned long

于 2009-11-11T23:46:55.363 回答