我正在使用本文中描述的 WELL512 伪随机数生成器函数。该函数返回一个随机unsigned long
值。
我如何使用这个返回值来产生一定范围内的随机实数——比如介于 340.92491 和 859812.53198 之间的浮点数。
C rand() 函数的文档似乎警告不要使用 mod。
好吧,从数学上讲,它只是:
min_value + (max_value - min_value) * (my_random() / (long double)ULONG_MAX)
(假设 my_random() 返回一个介于 0 和 ULONG_MAX 之间的均匀分布的数字)
但是,根据 、和的确切值min_value
,某些浮点数几乎肯定会比其他数字更有可能。max_value
ULONG_MAX
通过这个公式,每个可能的随机无符号长映射到一个浮点数。min_value
但是由于和之间的不同浮点数的数量max_value
几乎可以肯定不完全ULONG_MAX
,因此一些无符号长整数将映射到相同的浮点数,或者某些浮点数将没有无符号长整数映射到它们或两者。
解决这个问题以使结果真正统一是......我认为这不是微不足道的。也许有人比我读得更好,可以引用一篇论文。
[编辑]
或者查看这个问题的答案:
这个答案取决于 IEEEdouble
表示的内部结构。我也不确定我是否完全理解它是如何工作的。
[编辑 2]
好的,现在我明白它是如何工作的了。这个想法是在最小值和最大值之间选择一个随机浮点表示,然后以与其指数表示的比例成反比的概率将其丢弃。因为对于均匀分布,(比如说)1/2 和 1 之间的数字需要是 1 和 2 之间的数字的一半,但是这些范围内的浮点表示的数量是相同的。
我认为您可以通过首先在对数尺度上选择指数来提高代码效率 - 例如,通过使用ffs
随机选择的整数 - 然后随机选择尾数。嗯……
是否可以将实数转换为无符号长?如果这很容易做到,我认为 WELL512 有效。祝你好运。
使用浮点数表示均匀分布的实数是完全不可能的——在你的范围内有无数个实数,但只有有限个浮点数。
更糟糕的是,如果您的范围跨越浮点指数边界,那么您范围内可表示为浮点数的有限实数甚至可能不会均匀分布。