首页 > 解决方案 > 这个 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 吗?

标签: c++

解决方案


0x3f8000001.0f是以IEEE-754binary32单精度格式存储时的二进制表示。这种格式有 23 个存储的有效位(尾数)位。这些位由 32 位 PRNG 返回的 23 个高位填充,从而产生 [1, 2) 中的伪随机数。从结果中减去1.0f会在 [0, 1) 中得到一个随机数,然后将其缩放到区间 [a, b] 或 [a, b),具体取决于特定对a,的舍入方式b

正如其他人已经在评论中指出的那样,此代码中用于将 a 重新解释float为 a的类型双关语习语uint32_t是不安全的,因为它会调用未定义的行为。


推荐阅读