根据getNext模块中PCGRandom的手册页,我们可以生成给定范围内的随机数,例如:

use Random;

var rng1 = new owned RandomStream( eltType= real, seed= 100 );
var rng2 = new owned RandomStream( eltType= int,  seed= 100 );

for i in 1..5 do
    writeln( rng1.getNext( min= 3.0, max= 5.0 ) );

writeln();
for i in 1..5 do
    writeln( rng2.getNext( min= 20, max= 80 ) );
这给出(使用 chpl-1.20.0):
4.50371
4.85573
4.2246
4.84289
3.63607

36
57
79
39
57
在这里,我注意到手册页为整数和实数情况提供了以下注释:

(我用斜体来强调)。对于实数,这是否与所谓的“浮点数密度”有关,例如在 this page 中问)?另外,对于整数,是否有一些情况即使对于“典型”使用我们也需要小心?
(这里,“典型”意味着,例如,在给定范围内大致平坦分布的 10**8 个随机整数的生成。)
仅供引用,我的“用例”不是对随机数的严格质量测试,而只是典型的蒙特卡罗计算(例如,选择立方晶格上的随机点)。

最佳答案

手册页中的注释表明与已研究过的其他 PCG 随机数方法的不同(至少由 PCG 算法的作者)。

浮点数的问题确实与浮点数密度有关。请参阅 PCG 作者的 http://www.pcg-random.org/using-pcg-c-basic.html#generating-doubles。即使在 [0.0, 1.0] 中生成随机数也是一个潜在的问题。文档中的这一段描述了这个问题:



请注意,64 位实数可以存储与 2.0**-1024 一样小的数字,但是通过将正整数除以 2**64 来获得这样的数字是完全不可能的。 (在这里和上面我使用 ** 作为幂运算符,因为它在 Chapel 语法中就是这样做的)。我建议阅读 IEEE 浮点格式(例如 https://en.wikipedia.org/wiki/IEEE_754https://en.wikipedia.org/wiki/Double-precision_floating-point_format )以获取该领域的背景信息。如果您使用 RNG 为对 real(64) 值运行的算法生成测试输入,您可能会关心这一点。在这种情况下,您可能希望生成非常小的值。请注意,构建一个可以以非均匀方式生成所有 real(64) 值的 RNG 并不难(例如,只需将 uint 中的位复制到 real 中)。

关于你问题的另一部分:

我使用 TestU01 对特定范围内的随机整数的生成进行了一些基本的统计测试,我对它与蒙特卡罗计算的使用充满信心。但是,我不是这方面的专家,因此我将该警告放在了文档中。文档中的以下信息描述了我所做的测试:

关于random - 生成给定范围内的随机整数和实数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60045891/

10-14 17:46
查看更多