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