【发布时间】:2021-05-25 13:32:15
【问题描述】:
我有这段 C 代码,它将 binary64 值随机舍入为 binary32。问题是我不太完全理解代码。我知道它直接对浮点数的位进行操作,但我无法理解发生了什么。能否请您与我分享一些见解?
float function(double x){
uint64_t temp = *(uint64_t*)&x;
uint32_t r = (rand() * (0xFFFFFFFF/RAND_MAX)) % 0x1FFFFFFF;
temp += r;
temp = temp & 0xFFFFFFFFE0000000;
return (float)*(double *)&temp;
}
位掩码代表什么? (我的直觉告诉我这与指数和尾数如何以二进制格式表示有关,但我无法将其可视化)
为什么随机变量 r 是这样计算的?
通过代码进行的交互会是什么样子?
【问题讨论】:
-
似乎是特定于平台的,但请扩展为可编译的示例,以便我们查看机器代码。
-
0xFFFFFFFFE0000000涵盖binary64的 1 个符号位 + 11 个指数位 + 23 个尾数位,其中最后一个是binary32中的尾数位数。所以除了上溢/下溢,temp的最终值应该无损地转换成binary32。0x1FFFFFFF覆盖了binary64数字的29个低位尾数,它们用于四舍五入。 -
r只是生成一个介于 0 和 0x1FFFFFFF 之间的随机数——括号会产生一些混乱,模数会将其限制在该范围内。rand的大多数实现都很垃圾,它们不会是很好的随机数。 -
这种类型的双关语成语:
uint64_t temp = *(uint64_t*)&x;调用未定义的行为。我建议改用memcpy();现代编译器知道如何优化这一点。 -
@njuffa 你的解释很有见地,非常感谢。同样,感谢所有评论
标签: c floating-point bit-manipulation rounding stochastic