直观地,可以按如下方式编写随机双生成器:
double randDouble(double lowerBound, double upperBound)
{
double range = upperBound - lowerBound;
return lowerBound + range * rand();
}
假设我们假设rand()
在区间[0,1]上返回均匀分布的伪随机双重。
这种方法是否保证在[lowerBound,upperBound]内以均匀的概率分布返回随机双精度?我特别感兴趣的是浮点计算的性质是否会在某些范围的最终分布中引起尖峰或下降。
答案 0 :(得分:2)
首先,rand()生成伪随机数字,而不是真正随机的。因此,我假设您在询问您的函数是否在指定范围内生成伪随机数。
其次,就像Oli Charlesworth所说,许多rand实现返回0到RAND_MAX之间的数字,其中RAND_MAX是它可以采用的最大可能值。在这些情况下,您可以使用
获取[0,1]中的值double r = rand()/((double)RAND_MAX+1);
+1
就在那里,r不能为1.
其他语言的rand返回0到1之间的值,在这种情况下,您不需要执行上述除法。无论哪种方式,事实证明你的函数返回一个相当随机分布的近似值。请参阅以下链接以获取更多详细信息:http://www.thinkage.ca/english/gcos/expl/c/lib/rand.html请注意,此链接为您提供了稍微不同的功能,他们声称这些功能更好一些,但您可能已经运行得很好。
答案 1 :(得分:2)
如果你的上限和下限是2的相邻幂,那么你得到的分布将与你从rand()
获得的分布一样好,因为你实际上只是在改变{{1}的指数。给你,而不改变尾数。
如果要扩展范围以覆盖多于2的幂,那么在您的方法的下半部分中将存在永远不会生成的有效浮点数。 (你有效地将尾数的一个或多个位移到指数中,使尾数的最低有效位保持为非随机。)
如果在更一般的范围内使用该方法(通过计算修改尾数),那么在尝试将随机整数转换为随机整数时,您也会遇到相同的非均匀性modulo n ,不使用拒绝抽样。
任何用于生成浮点数均匀分布的正确方法都必须考虑到舍入到任何给定浮点数的实数的间隔并不总是相同的宽度。在范围的下半部分,浮点数将更加密集,因此该范围的那一部分中的每个浮点数应该比较大的数字选择的频率低。
答案 2 :(得分:1)
嗯,不。 rand()
返回0到RAND_MAX
之间的数字;这种量化会给你的发行带来很大的漏洞;实际上,几乎所有lowerBound
和upperBound
之间的浮点值都不会被选中。