从随机字节生成随机浮点数而无需位旋转

Generate random floats from random bytes without bit-twiddling

假设我有足够好的 (tm) 随机字节值流,是否有一种数学方法可以将它们转换为 (0 < n < 1) 不需要知道内部格式的浮点值的花车?

我正在寻找这样的东西:

天真的解决方案是只用几个字节为自己构建一个大整数,然后简单地转换为除以 2^n 的浮点数,但我看不出如何在不弄乱分布的情况下做到这一点。

另一个想法是这样的(伪代码):

state := 0.0
n := requiredIterations(outputPrecision)
for(1..n)
    nextByte := getRandomByte()
    state := state + nextByte
    state := state / 256
end
return state

看起来这应该可行,但我不知道如何证明它:)

正如 Severin Pappadeux 所说,为什么不做类似的事情

const double factor = 2.32830643653869628906e-10;    // 2^(-32)
unsigned int accumulator = 0;
for (int i = 0; i != 4; ++i)
{
    accumulator <<= 8;
    accumulator |= getRandomByte();
}
double r = factor * accumulator;

好的,我想我有你需要的东西

让我们考虑按以下方式在 [0...1) 范围内对浮点数进行采样。 256 是 2^8,相当于下一个字节移位。让我们将字节合并为

b0*256*256*256 + b1*256*256 + b2*256 + b3

要获得 [0...1) 范围内的数字,您必须将其除以 256*256*256*256,因此

f = b0/256 + b1/(256*256) + b2/(256*256*256) + b3/(256*256*256*256)

这又等同于多项式计算的 Horner 方案

f = (1/256)*(b0 + (1/256)*(b1 + (1/256)*(b2 + (1/256)*b3)))

反过来,这几乎是你写的(对于一些抽象的 N)