c++ - 这个 randfloat() 有什么作用?
问题描述
我看到了一些 C++ 代码:
float randfloat(float a, float b)
{
uint32_t val = 0x3F800000 | (rng.getU32() >> 9);
float fval = *(float *)(&val);
return a + ((fval - 1.0f) * (b - a));
}
完整的代码在Github gist上。似乎首先将二进制数111111100000000000000000000000
与右移 9 个位置的无符号随机整数按位或。
然后将这些位视为浮点数,并制成浮点数?我猜它会返回一个浮点数,它是一个介于a
和之间的随机数b
,具有a
包容性和b
排斥性。所以代码的其他一些部分使用randfloat(0.9, 0.85)
,我认为它“几乎”与 相同randfloat(0.85, 0.9)
,除了第一种情况不包括0.85
,而第二种情况不包括0.9
。
有人知道这部分发生了什么0x3F800000 | (rng.getU32() >> 9)
并使它成为浮动 - 它是 IEEE 754 吗?
解决方案
0x3f800000
1.0f
是以IEEE-754binary32
单精度格式存储时的二进制表示。这种格式有 23 个存储的有效位(尾数)位。这些位由 32 位 PRNG 返回的 23 个高位填充,从而产生 [1, 2) 中的伪随机数。从结果中减去1.0f
会在 [0, 1) 中得到一个随机数,然后将其缩放到区间 [a, b] 或 [a, b),具体取决于特定对a
,的舍入方式b
。
正如其他人已经在评论中指出的那样,此代码中用于将 a 重新解释float
为 a的类型双关语习语uint32_t
是不安全的,因为它会调用未定义的行为。
推荐阅读
- bash - 在 Bash 中更改只读环境变量
- spring - 如何使用 Java 的常量值作为 th:value 名称?
- haskell - a->a->Ordering 是否有一个简短的 Lambda 表达式?
- c++ - 在 C++ 中使用 istringstream
- python - 如何将文本文件的多行作为字典中键的值(在元组中)?
- javascript - AngularJS Material - 在 md-radio-button 上进行 ng-checked,以 ng-value 作为对象
- javascript - 操纵同一类的两个“背景”
- python - SQL注入 MariaDB python CTF
- ios - StackView 子视图常量宽度
- java - java,如何将 json ajax 数据解析为 jsonArray?(使用 @requestparam 映射,而不是 VO)