回 帖 发 新 帖 刷新版面

主题:c++如何产生覆盖范围极大的随机数?

我用过rand(),但满足不了要求。我要求的随机数是0-1之间(开区间),最小值小于10^-9,并且(0-1)中的所有数出现的概率都是一样大的(也就是均匀分布),这一点rand()似乎做不到。如何产生呢?请各位指教。

回复列表 (共7个回复)

沙发

我的想法是这样的.
我假设 rand() 能产生 1-1000 的随机数,(如果假设不成立,可以造一个函数使其成立)
我要产生 1-2000 的随机数,
我可以这样,先随即产生 0,1 两个数,
如果是0,
那么再调用 rand() 产生1-1000的数,
把这个数返回.
如果是1,
那么也调用 rand()产生1-1000的数,
把这个数+1000返回.

用这种方法可以产生 1-10^9 的随机数.
再取倒数就可以了.
注意,取倒数时应该用 double ,因为 double 有15位的精度.

板凳

别费心思了,理论上做不到

“并且(0-1)中的所有数出现的概率都是一样大的”
--- 0-1之间有多少个数?
如果以10^-9为最小单位,但float并非以均匀间隔表示实数的

3 楼

C函数rand通常只能产生16位的随机数,而且速度很慢。

如果你需要32位的随机数或者需要产生更大分布范围的浮点随机数,可以采取以下任何一种方案。

1、用boost,调用产生均匀分布随机数的相关函数。

2、到我的主页上去看看随机数设计理论,自己设计或者干脆下载随机数产生程序代码,自己加上几行代码,产生你需要的随机数。

以上两种方法产生随机数的速度大约比C函数rand快3倍左右。

3、如果需要64位的随机数或者希望随机数产生的速度更快,可以自己写,不会写就给我写信。

4 楼

C函数rand两次相乘可以产生更大范围的随机数,只不过容易产生二次聚集,也就是说随机性变得更差

5 楼

[quote]两次相乘[/quote]
不能相乘

假设某个rand产生 0 1 2 这三个随机数
如果相乘,结果将是 0 0 0 0 1 2 0 2 4,即产生 0(5/9) 1(1/9) 2(2/9) 4(1/9) 四个随机数,且几率不再相等。
应该使用 rand()*随机数范围+rand() 这个公式。假设某个rand产生 0 1 2 这三个随机数
rand()*3+rand() 将产生 0 1 2 3 4 5 6 7 8 这9个随机数,且几率都相同。
对于C/C++中标准的rand函数,扩展公式就是 rand()*(RAND_MAX+1)+rand()

6 楼

[quote]
对于C/C++中标准的rand函数,扩展公式就是 rand()*(RAND_MAX+1)+rand()
[/quote]
哈哈,我没看过C/C++标准也想到了,哈哈哈哈哈...

7 楼

[quote][quote]两次相乘[/quote]
不能相乘

假设某个rand产生 0 1 2 这三个随机数
如果相乘,结果将是 0 0 0 0 1 2 0 2 4,即产生 0(5/9) 1(1/9) 2(2/9) 4(1/9) 四个随机数,且几率不再相等。
应该使用 rand()*随机数范围+rand() 这个公式。假设某个rand产生 0 1 2 这三个随机数
rand()*3+rand() 将产生 0 1 2 3 4 5 6 7 8 这9个随机数,且几率都相同。
对于C/C++中标准的rand函数,扩展公式就是 rand()*(RAND_MAX+1)+rand()[/quote]

相乘会向一处聚集,rand()*(RAND_MAX+1)+rand()会向两处聚集。如果需要更大范围的随机数,最好别用rand

我来回复

您尚未登录,请登录后再回复。点此登录或注册