这个问题与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
的按位AND来存储分数?
据我了解,f - (int) f
始终是一个满足不等式0 <= f - (int) f < 1
的数字。由于这个数字总是小于1,这个数字乘以65536总是小于65536.换句话说,这个数字在二进制表示中永远不会超过16位。
如果这个数字的长度永远不会超过16位,那么尝试用& 0xffff
选择最低有效16位是什么意思。这对我来说似乎是一个多余的步骤。
& 0xffff
这个功能正常工作所必需的场景?
答案 0 :(得分:1)
& 0xffff
是多余的。
甚至使用都值得怀疑。考虑以下。如果某些先前或未来的代码可能会创建some_float_expression < 0
或some_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);