简体   繁体   English

如何将浮点数转换为无符号变量?

[英]How to convert floating-point to unsigned variable?

Could someone please help me with byte ordering regarding floating point variables? 有人可以帮我有关浮点变量的字节排序吗? Actually the code is working correctly on Solaris, but not on Windows Xp. 实际上,该代码在Solaris上可以正常工作,但在Windows Xp上却不能正常工作。 Here is a piece example of my code: .... 这是我的代码的一个示例:....

 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 code was compiled with gcc on Unix and with MSVC++6 on wndows. 代码在Unix上使用gcc编译,在wndows上使用MSVC ++ 6编译。 Any of your help would be very appreciated and I would be glad if you could direct me to any link or document that gives usefull information about endianness ... 您的任何帮助将不胜感激,如果您可以将我定向到任何提供有关字节序有用信息的链接或文档,我将非常高兴...

Thanking you in advance for your help, mk 预先感谢您的帮助,mk

This is a generally bad idea. 这通常是个坏主意。 The format of floating point numbers isn't necessarily the same on different hardware, even after accounting for byte order. 即使考虑了字节顺序,浮点数的格式在不同的硬件上也不一定相同。 I would have to recommend shipping them here and there as strings. 我将建议您在这里和那里以字符串形式运送它们。

There's a lot more potential variety and issues in floating point formats than just the endian problem you have to deal with when marshalling and unmarshalling integers. 浮点格式中存在更多的潜在多样性和问题,而不仅仅是在编组和解组整数时要处理的字节序问题。

One way out is to format floating point numbers as text, using printf , and reading them back with strtof() (as bmargulies indicated). 一种解决方法是使用printf将浮点数格式化为文本,并使用strtof()读回它们(如bmargulies所示)。

Another way that will work as long as the machines share the same FLT_RADIX value, is to break them into a mantissa and exponent value: 只要机器共享相同的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;

You then have an int and a long ( x_exp and x_mant from the above code) to put onto the wire, which you can use the normal ntohl() and htonl() functions to do. 然后,您需要将一个int和一个long (上面的代码中的x_expx_mant )放置到线路上,您可以使用常规的ntohl()htonl()函数来完成此操作。 To convert these back into a float , use: 要将它们转换回float ,请使用:

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

Note that most machines have a FLT_RADIX value (defined in float.h ) of 2, so if you check for that during compilation and abort if it's something else, you should be reasonably portable. 请注意,大多数计算机的FLT_RADIX值(在float.h定义)为2,因此,如果在编译过程中检查该值,并在其他情况下中止该值,则应该具有可移植性。

Assuming both systems have the same floating point format, yy_rec is a float ; 假设两个系统具有相同的浮点格式,则yy_recfloat ntohl takes an unsigned long ; ntohlunsigned long ntohl ; the floating point value, potentially with incorrect endianness, is being converted to an integer representation when it is passed into ntohl . 当传递给ntohl时,可能具有不正确字节序的浮点值将转换为整数表示形式。

You should be getting a compiler warning due to the conversion from float to unsigned long . 由于从floatunsigned long的转换,您应该收到编译器警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM