srand(time(null));
printf("%d", rand());
Run Code Online (Sandbox Code Playgroud)
给出一个高范围的随机数(0-32000ish),但我只需要大约0-63或0-127,但我不知道如何去做.有帮助吗?
Tyl*_*nry 61
rand() % (max_number + 1 - minimum_number) + minimum_number
Run Code Online (Sandbox Code Playgroud)
所以,对于0-65:
rand() % (65 + 1 - 0) + 0
Run Code Online (Sandbox Code Playgroud)
(显然你可以将0关闭,但它是完整的).
请注意,这会略微偏向随机性,但如果您没有做一些特别敏感的事情,可能没有什么可担心的.
小智 16
检查一下
http://c-faq.com/lib/randrange.html
对于这些技术中的任何一种,如果需要,可以直接改变范围; [M,N]范围内的数字可以用类似的东西生成
M + rand() / (RAND_MAX / (N - M + 1) + 1)
Run Code Online (Sandbox Code Playgroud)
Vit*_*.us 10
你可以用这个:
int random(int min, int max){
return min + rand() / (RAND_MAX / (max - min + 1) + 1);
}
Run Code Online (Sandbox Code Playgroud)
来自:
comp.lang.c常见问题列表·问题13.16
问:如何在一定范围内获得随机整数?
答:显而易见的方式,
Run Code Online (Sandbox Code Playgroud)rand() % N /* POOR */(试图将数字从0返回到N-1)很差,因为许多随机数发生器的低位比特是令人沮丧的非随机的.(参见问题13.18.)更好的方法是类似的
Run Code Online (Sandbox Code Playgroud)(int)((double)rand() / ((double)RAND_MAX + 1) * N)如果你不想使用浮点,另一种方法是
Run Code Online (Sandbox Code Playgroud)rand() / (RAND_MAX / N + 1)如果你只需要用概率1/N做一些事情,你可以使用
Run Code Online (Sandbox Code Playgroud)if(rand() < (RAND_MAX+1u) / N)所有这些方法显然需要知道RAND_MAX(<stdlib.h>中的ANSI #defines),并假设N远小于RAND_MAX.当N接近RAND_MAX时,如果随机数发生器的范围不是N的倍数(即,如果(RAND_MAX + 1)%N!= 0),则所有这些方法都会中断:某些输出比其他.(使用浮点没有帮助;问题是rand返回RAND_MAX + 1个不同的值,这些值不能总是均匀地分配到N个桶中.)如果这是一个问题,你唯一能做的就是调用rand multiple次,丢弃某些值:
Run Code Online (Sandbox Code Playgroud)unsigned int x = (RAND_MAX + 1u) / N; unsigned int y = x * N; unsigned int r; do { r = rand(); } while(r >= y); return r / x;对于这些技术中的任何一种,如果需要,可以直接改变范围; [M,N]范围内的数字可以用类似的东西生成
Run Code Online (Sandbox Code Playgroud)M + rand() / (RAND_MAX / (N - M + 1) + 1)(顺便说一下,RAND_MAX是一个常数,告诉你C库rand函数的固定范围是什么.你不能将RAND_MAX设置为其他值,并且无法 在其他范围内请求rand返回数字.)
如果你从一个随机数生成器开始,它返回0到1之间的浮点值(例如问题13.15中提到的PMrand的最后一个版本 ,或问题13.21中的 drand48 ),你需要做的就是从中获取整数0到N-1将该生成器的输出乘以N:
Run Code Online (Sandbox Code Playgroud)(int)(drand48() * N)参考文献:K&R2 Sec.7.8.7 p.168
PCS Sec.11 p.172
引自:http://c-faq.com/lib/randrange.html
天真的方法是:
int myRand = rand() % 66; // for 0-65
Run Code Online (Sandbox Code Playgroud)
这可能是一个非常轻微的不均匀分布(取决于您的最大值),但它非常接近。
要解释为什么它不是很统一,请考虑这个非常简化的示例:
假设 RAND_MAX 是 4,并且您想要一个 0-2 之间的数字。您可以获得的可能值如下表所示:
rand() | rand() % 3
---------+------------
0 | 0
1 | 1
2 | 2
3 | 0
Run Code Online (Sandbox Code Playgroud)
看到问题了吗?如果您的最大值不是 RAND_MAX 的偶数除数,您将更有可能选择较小的值。但是,由于 RAND_MAX 通常为 32767,因此偏差可能小到足以满足大多数目的。
有多种方法可以解决这个问题;有关 Java 如何处理它的解释,请参见此处Random。
取其结果的模数,正如其他海报所宣称的那样,会给你一些几乎随机的东西,但并不完美.
考虑这个极端的例子,假设你想模拟抛硬币,返回0或1.你可以这样做:
isHeads = ( rand() % 2 ) == 1;
Run Code Online (Sandbox Code Playgroud)
看起来很无害,对吧?假设RAND_MAX只有3.它当然要高得多,但这里的要点是当你使用一个不均匀划分RAND_MAX的模数时存在偏差.如果你想要高质量的随机数,你就会遇到问题.
考虑我的例子.可能的结果是:
rand() freq. rand() % 2
0 1/3 0
1 1/3 1
2 1/3 0
Run Code Online (Sandbox Code Playgroud)
因此,"尾巴"的发生频率是"头"的两倍!
阿特伍德先生在这篇编码恐怖文章中讨论了这个问题
rand()将返回 0 到 RAND_MAX 之间的数字,至少是 32767。
如果你想得到一个范围内的数字,你可以使用 modulo。
int value = rand() % 66; // 0-65
Run Code Online (Sandbox Code Playgroud)
为了更准确,请查看这篇文章。它讨论了为什么模不一定是好的(不好的分布,特别是在高端),并提供了各种选择。
更新为不使用 #define
double RAND(double min, double max)
{
return (double)rand()/(double)RAND_MAX * (max - min) + min;
}
Run Code Online (Sandbox Code Playgroud)
double scale = 1.0 / ((double) RAND_MAX + 1.0);
int min, max;
...
rval = (int)(rand() * scale * (max - min + 1) + min);
Run Code Online (Sandbox Code Playgroud)
正如其他人所指出的那样,简单地使用模数会使个别数字的概率产生偏差,因此较小的数字是首选.
Java的java.util.Random类中使用了一个非常巧妙和良好的解决方案:
public int nextInt(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0);
return val;
}
Run Code Online (Sandbox Code Playgroud)
我花了一段时间才明白它为什么会起作用,我把它留作读者的练习,但它是一个非常简洁的解决方案,可确保数字具有相同的概率.
这段代码中的重要部分是while循环的条件,它拒绝落在数字范围内的数字,否则会导致分布不均匀.
如果您不太关心低位的“随机性”,只需 rand() % HI_VAL 即可。
还:
(double)rand() / (double)RAND_MAX; // lazy way to get [0.0, 1.0)
Run Code Online (Sandbox Code Playgroud)