如何在网络上进行浮点数的序列化?

dee*_*sky 1 c floating-point serialization

我发现了一段代码来对网络上的浮点数进行序列化.

uint32_t htonf(float f)
{
    uint32_t p;
    uint32_t sign;

    if (f < 0) { sign = 1; f = -f; }
    else { sign = 0; }

    p = ((((uint32_t)f)&0x7fff)<<16) | (sign<<31); // whole part and sign
    p |= (uint32_t)(((f - (int)f) * 65536.0f))&0xffff; // fraction

    return p;
}
Run Code Online (Sandbox Code Playgroud)

规范:上面的代码是一种天真的实现,它存储一个32位数的浮点数.高位(31)用于存储数字的符号("1"表示负数),接下来的7位(30-16)用于存储浮点数的整数部分.最后,剩余的比特(15-0)用于存储数字的小数部分.

其他人都很好,但我无法弄清楚这意味着什么.这怎么能让我们得到15-0位?为什么我们需要"*65536.0f"?

p |= (uint32_t)(((f - (int)f) * 65536.0f))&0xffff
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下吗?

Mik*_*ale 5

f - (int)f
Run Code Online (Sandbox Code Playgroud)

为您提供数字的小数部分.您希望将此分数存储为16位,因此将其视为分数为2 ^ 16作为分母.分子是:

(f - (int)f) * 65536.0f)
Run Code Online (Sandbox Code Playgroud)

其余的只是使用位移将其打包到32位数的正确位中.然后,32位int在网络上像任何其他32位int一样被序列化,并且可能与上述例程相反,用于重新创建浮点数.