此问题与 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
是多余的。
连用都值得怀疑。考虑以下。如果某些先前或 future 可能的代码可能会创建 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);
关于c - 为什么按位与 0xffff 在 (uint32_t)(((f - (int)f) * 65536.0f))&0xffff 中实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40066818/