【发布时间】:2019-12-04 18:51:55
【问题描述】:
我正在尝试通过网络发送一个包含浮点数据的结构,该结构由两种不同的硬件架构组成,用 C 语言编写。
客户端运行在x86_64架构上,服务器运行在PPC(32位)架构上。
似乎我将数据转换为网络友好格式和从网络友好格式转换的唯一选择是:
htons/ntohs(2 字节)和htonl/ntohl(4 字节)
似乎没有处理浮点数的版本(这是有道理的,因为不同的架构/字节序有不同的浮点数表示)。
因此,我尝试通过以下方式将浮点数拆分为整数和指数格式:
void FtoME(float num, int32_t* mantissa, int32_t* exponent)
{
int32_t sig = (int32_t)num;
int32_t exp = 0;
double frac = num-sig;
double temp = num;
while (frac > 0 && exp > -20)
{
temp = temp * 10; //left shift the whole number
sig = (int32_t)temp; //get the integer part
frac = temp - sig; //get the fractional part
exp--;
}
printf("Scientific note: %dx10^%d\n",sig, exp);
*mantissa = sig;
*exponent = exp;
}
现在,虽然这在理论上确实有效,但在实践中,我遇到了很多溢出,所以很明显,这不是处理这个问题的正确方法。
是否有其他方法可以避免溢出,并将浮点数转换为网络友好格式(重要的是,再次返回),同时不丢失任何数据?
【问题讨论】:
-
唯一几乎通用的数据传输方式是纯 UTF-8 编码文本。任何形式的二进制数据总会有特殊或极端的情况,在这些情况下,要在所有现在生活的平台和系统中以可移植的方式正确处理它是非常困难的。
-
定义传输协议并坚持下去。如果您的传输格式是“big endian 32-bit IEEE 754”,那么各方都必须对此达成一致。如果您计划支持奇怪的架构,您可能需要使用预处理器定义,但通常您可以期望只担心字节顺序,即this answer to a very similar question。
-
“当您有设计复杂二进制文件格式或复杂二进制应用程序协议的冲动时,通常最好躺下直到感觉过去”——Eric Steven Raymond 在The Art of Unix Programming, chapter 5
标签: c network-programming computer-science