这个问题与Section 7.4 of Beej's Guide to Network Programming中的代码示例有关。

这是代码示例。

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;
}


为什么需要与0xffff进行按位与运算以存储分数?

据我了解,f - (int) f始终是满足不等式0 <= f - (int) f < 1的数字。由于此数字始终小于1,因此该数字乘以65536始终小于65536。换句话说,此数字在其二进制表示形式中永远不会超过16位。

如果该数字的长度从不超过16位,那么尝试使用& 0xffff选择最低有效16位的意义何在?对我来说,这似乎是多余的一步。

你同意吗?还是看到需要& 0xffff才能使此功能正常工作的情况?

最佳答案

& 0xffff是多余的。

甚至使用都值得怀疑。考虑以下。如果某些先前的代码或将来可能使用的代码可能会创建some_float_expression < 0some_float_expression >= 0x10000,则用& 0xffff截断表达式可能会导致错误的答案。以下就足够了。

(uint32_t)(some_float_expression);


IMO,代码还有其他问题:


没有范围错误检测。 @M.M
我希望能进行四舍五入的转换,而不是将其截断为0.0。
次要:if (f < 0)是用于检测-0.0f的符号的错误测试。使用signbit()
不清楚为什么代码不像

if (in range)
  p = (uint32_t)(f*65536.0f) | (sign<<31);

关于c - 为什么在(uint32_t)((((f-(int)f)* 65536.0f))&0xffff中实现0xffff的按位与运算?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40066818/

10-11 15:45