C语言 - 随机数生成器

15

我该如何生成一个在0和1之间的随机数?


5
真正的随机还是伪随机? - tvanfosson
@tm1 -- 伪随机数仅近似于随机数的属性,并不一定适用于需要真正随机性的应用,例如密码学。请参阅http://en.wikipedia.org/wiki/Pseudorandom_number_generator以获取解释。 - tvanfosson
@KennyTM 你有骰子,其面可以相加得到0到1之间的任何实数?令人印象深刻。 - Tyler McHenry
2
重复多次:https://dev59.com/wUjSa4cB1Zd3GeqPG596 https://dev59.com/n3RA5IYBdhLWcg3wzhNY https://dev59.com/NnM_5IYBdhLWcg3w6X5e 等等。顺便说一下,@tm1,我发现通过这个搜索 http://stackoverflow.com/search?q=[c]+random+number。 - dmckee --- ex-moderator kitten
@N1.1 严格来说,这并不重要 :) - Alexei Averchenko
显示剩余5条评论
3个回答

22

您可以使用stdlib.h来生成伪随机数。只需包含 stdlib,然后调用

double random_number = rand() / (double)RAND_MAX;

2
参考值将在[0.0,1.0]范围内,即包括0.0和1.0。 - Philip Potter
3
最重要的是,它很可能不会公平!在许多实现中,区间[0.0, 1.0]包含的元素数量超过了RAND_MAX。 (在C语言中,区间[0.0, 1.0]是一个可数有限集合。) - MSalters
@MSalters,这是一个有趣的问题,你对解决方案有什么想法吗? - Mark Elliot
1
这真的取决于应用程序。首先要认识到的是,集合 [0.00,0.01] 包含的元素比集合 [0.99,1.00] 多得多。这是因为 1E-100>0 但是 1-1E-100 == 1。对于许多应用程序,可以通过设置 p(x) = 1.0/(_nextafter(x)-x); 来抵消这种影响,尽管这在技术上适用于范围 [0.0,1.0)。结果是 p(x) 取决于 x,但是 SUM[0<=i < x](p(i)) == x - MSalters
1
噢,而且通常这并不重要 - 许多应用程序即使使用double arr[11] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 }; return arr[rand % 11];也可以正常工作。 - MSalters

9
假设 OP 希望得到 0 或 1:
srand(time(NULL));
foo = rand() & 1;

受评论启发的修改: 旧的rand()实现有一个缺陷 - 低位比高位的周期要短得多,因此在这种实现中使用低位并不好。 如果您知道您的rand()实现存在此问题,请使用高位,像这样:

foo = rand() >> (sizeof(int)*8-1)

在假定每字节有8位的普通体系结构下


1
你应该移位 rand() 的结果,以解决线性同余生成器的问题。 - Christoph
6
谁说 rand() 使用了所有的32位?例如在MSVC上,RAND_MAX 是0x7fff(http://msdn.microsoft.com/en-us/library/2dfe3bzd%28VS.80%29.aspx)。请注意,这个翻译保留了原文中的所有信息和意思,同时使其更加通俗易懂。 - kennytm
2
如果您使用 rand() >> (sizeof(int)*CHAR_BIT-1),则无需假定每个字节为8比特。 - Philip Potter
使用任意移位 (rand() >> RAND_SHIFT) & 1 并在编译时检查 RAND_MAX > (1 << RAND_SHIFT);或者,如果 RAND_MAX 的形式为 2^n - 1,则可以使用 rand() / ((RAND_MAX + 1) >> 1) 来获取最高有效位;你可以再次通过 (RAND_MAX & (RAND_MAX + 1)) == 0 在编译时进行检查。 - Christoph
1
@MSalters:使用rand() / (RAND_MAX + 1)不是总会得到0吗? - kennytm
显示剩余2条评论

8
man 3 drand48 恰好符合您的要求。

drand48()erand48() 函数返回非负的双精度浮点数,均匀分布于区间 [0.0, 1.0]。

这些函数可在 UNIX 平台上的 #include <stdlib.h> 中找到。但它们不在 ANSI C 中,因此(例如)在 Windows 上找不到它们,除非您自己带来实现(例如 LibGW32C)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接