srand(time(null));
printf("%d", rand());
给出一个高范围的随机数(0-32000ish),但我只需要大约0-63或0-127,但我不知道如何去做。有什么帮助吗?
答案 0 :(得分:56)
rand() % (max_number + 1 - minimum_number) + minimum_number
所以,对于0-65:
rand() % (65 + 1 - 0) + 0
(显然你可以将0关闭,但它是完整性的。)
请注意,这会略微偏倚随机性,但如果您没有做一些特别敏感的事情,可能没有什么可担心的。
答案 1 :(得分:16)
点击这里
http://c-faq.com/lib/randrange.html
对于这些技术中的任何一种,如果需要,可以直接改变范围; [M,N]范围内的数字可以用
之类的东西生成M + rand() / (RAND_MAX / (N - M + 1) + 1)
答案 2 :(得分:7)
您可以使用:
int random(int min, int max){
return min + rand() / (RAND_MAX / (max - min + 1) + 1);
}
来自:
comp.lang.c常见问题清单·问题13.16
问:如何在一定范围内获得随机整数?
答:显而易见的方式,
rand() % N /* POOR */
(试图将数字从0返回到N-1)很差,因为 许多随机数发生器的低阶位令人沮丧 非随机。 (参见问题13.18。)更好的方法就像
(int)((double)rand() / ((double)RAND_MAX + 1) * N)
如果您不想使用浮点,则另一种方法是
rand() / (RAND_MAX / N + 1)
如果你只需要用概率1 / N做某事,你可以使用
if(rand() < (RAND_MAX+1u) / N)
所有这些方法显然需要知道RAND_MAX(ANSI #defines in&lt; stdlib.h&gt;),并假设N远小于RAND_MAX。当N接近RAND_MAX时,如果是随机数的范围 生成器不是N的倍数(即,如果(RAND_MAX + 1)%N!= 0),则全部 这些方法中断了一些:一些产出的发生频率高于 其他。 (使用浮点没有帮助;问题是兰特 返回RAND_MAX + 1个不同的值,这些值不能始终均匀 分成N桶。)如果这是一个问题,那就是唯一的问题 你可以做的是多次调用rand,丢弃某些值:
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]范围内的数字
之类的东西M + rand() / (RAND_MAX / (N - M + 1) + 1)
(顺便说一下,RAND_MAX是一个常量告诉你是什么 固定范围的C库 rand 功能是。您无法设置RAND_MAX 其他一些价值,并且无法请求 rand 返回其他范围内的数字。)
如果你是从一个返回的随机数发生器开始的话 浮点值介于0和1之间(例如最后一个版本的 PMrand 提到问题13.15或drand48 13.21),你需要做的就是从0到N-1得到整数 将该生成器的输出乘以N:
(int)(drand48() * N)
参考文献:K&amp; R2 Sec。 7.8.7 p。 168个
PCS Sec。 11 p。 172
答案 3 :(得分:6)
取结果的模数,正如其他海报所断言的那样,会给你一些几乎随机的东西,但并非如此。
考虑这个极端的例子,假设你想要模拟抛硬币,返回0或1.你可以这样做:
isHeads = ( rand() % 2 ) == 1;
看起来无害,对吗?假设RAND_MAX只有3.它当然要高得多,但这里的要点是当你使用一个不均匀划分RAND_MAX的模数时存在偏差。如果你想要高质量的随机数,你就会遇到问题。
考虑我的例子。可能的结果是:
rand() freq. rand() % 2
0 1/3 0
1 1/3 1
2 1/3 0
因此,“尾巴”的发生频率是“头”的两倍!
先生。 Atwood讨论了这个问题in this Coding Horror Article
答案 4 :(得分:5)
正如其他人所指出的那样,仅使用模数会使个别数字的概率发生偏差,因此较小的数字是首选。
在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;
}
我花了一段时间才明白它为什么会起作用,我把它作为读者的练习,但这是一个非常简洁的解决方案,可确保数字具有相同的概率。
该段代码中的重要部分是while
循环的条件,它拒绝数字范围内的数字,否则会导致分布不均。
答案 5 :(得分:3)
double scale = 1.0 / ((double) RAND_MAX + 1.0);
int min, max;
...
rval = (int)(rand() * scale * (max - min + 1) + min);
答案 6 :(得分:2)
天真的做法是:
int myRand = rand() % 66; // for 0-65
这可能是一个非常不均匀的分布(取决于你的最大值),但它非常接近。
要解释为什么它不是很均匀,请考虑这个非常简单的例子:
假设RAND_MAX为4,你想要一个0-2的数字。您可以获得的可能值显示在此表中:
rand() | rand() % 3
---------+------------
0 | 0
1 | 1
2 | 2
3 | 0
看到问题?如果您的最大值不是RAND_MAX的偶数除数,则您更有可能选择较小的值。但是,由于RAND_MAX通常为32767,因此偏差可能很小,足以在大多数情况下逃脱。
有各种方法可以解决这个问题;有关Java Random
如何处理它的解释,请参阅here。
答案 7 :(得分:2)
更新为不使用#define
double RAND(double min, double max)
{
return (double)rand()/(double)RAND_MAX * (max - min) + min;
}
答案 8 :(得分:2)
如果你不太关心低位的“随机性”,只需rand()%HI_VAL。
此外:
(double)rand() / (double)RAND_MAX; // lazy way to get [0.0, 1.0)
答案 9 :(得分:1)
rand()将返回介于0和RAND_MAX之间的数字,至少为32767.
如果你想得到一个范围内的数字,你可以使用modulo。
int value = rand() % 66; // 0-65
为了更准确,check out this article。它讨论了为什么模数不一定好(坏分布,特别是在高端),并提供各种选项。
答案 10 :(得分:1)
此答案不关注随机性,而是算术顺序。 要获得一个范围内的数字,通常我们可以这样:
// the range is between [aMin, aMax]
double f = (double)rand() / RAND_MAX;
double result = aMin + f * (aMax - aMin);
但是,(aMax-aMin)可能会溢出。例如。 aMax = 1,aMin = -DBL_MAX。一种更安全的方式是这样写:
// the range is between [aMin, aMax]
double f = (double)rand() / RAND_MAX;
double result = aMin - f * aMin + f * aMax;
基于此概念,类似的事情可能会引起问题。
rand() % (max_number + 1 - minimum_number) + minimum_number
// 1. max_number + 1 might overflow
// 2. max_number + 1 - min_number might overflow
答案 11 :(得分:0)
我认为以下是半正确的。自从我触及C以来已经有一段时间了。这个想法是使用除法,因为模数并不总是给出随机结果。我向RAND_MAX添加了1,因为有许多可能的值来自rand,包括0.由于范围也是0,所以我也加了1。我认为数学排列正确,避免整数数学问题。
#define MK_DIVISOR(max) ((int)((unsigned int)RAND_MAX+1/(max+1)))
num = rand()/MK_DIVISOR(65);
答案 12 :(得分:0)
如果您关心随机数的质量,请不要使用rand()
使用其他一些prng,如http://en.wikipedia.org/wiki/Mersenne_twister或其他高质量的prng之一
然后就去模数。
答案 13 :(得分:0)
只是为现有答案添加一些额外的细节。
mod %
操作将始终执行完整的除法,因此产生的余数小于除数。
x%y = x - (y * floor((x / y)))
具有注释的随机范围查找功能的示例:
uint32_t rand_range(uint32_t n, uint32_t m) {
// size of range, inclusive
const uint32_t length_of_range = m - n + 1;
// add n so that we don't return a number below our range
return (uint32_t)(rand() % length_of_range + n);
}
上述另一个有趣的属性:
x%y = x,如果x < ÿ
const uint32_t value = rand_range(1, RAND_MAX); // results in rand() % RAND_MAX + 1
// TRUE for all x = RAND_MAX, where x is the result of rand()
assert(value == RAND_MAX);
result of rand()
答案 14 :(得分:0)
2 cents (ok 4 cents):
n = rand()
x = result
l = limit
n/RAND_MAX = x/l
Refactor:
(l/1)*(n/RAND_MAX) = (x/l)*(l/1)
Gives:
x = l*n/RAND_MAX
int randn(int limit)
{
return limit*rand()/RAND_MAX;
}
int i;
for (i = 0; i < 100; i++) {
printf("%d ", randn(10));
if (!(i % 16)) printf("\n");
}
> test
0
5 1 8 5 4 3 8 8 7 1 8 7 5 3 0 0
3 1 1 9 4 1 0 0 3 5 5 6 6 1 6 4
3 0 6 7 8 5 3 8 7 9 9 5 1 4 2 8
2 7 8 9 9 6 3 2 2 8 0 3 0 6 0 0
9 2 2 5 6 8 7 4 2 7 4 4 9 7 1 5
3 7 6 5 3 1 2 4 8 5 9 7 3 1 6 4
0 6 5
答案 15 :(得分:0)
多次运行程序时,仅使用rand()即可为您提供相同的随机数。即,当您第一次运行程序时,它将产生随机数x,y和z。如果再次运行该程序,它将产生与我观察到的相同的x,y和z数。
我发现每次都保持唯一性的解决方案是使用srand()
这是附加代码,
#include<stdlib.h>
#include<time.h>
time_t t;
srand((unsigned) time(&t));
int rand_number = rand() % (65 + 1 - 0) + 0 //i.e Random numbers in range 0-65.
要设置范围,您可以使用公式:rand()%(max_number +1-minimum_number)+ minimum_number
希望有帮助!
答案 16 :(得分:-1)
您可以通过在rand函数之前添加一个%来更改代码
例如:
rand() % 50
将为您提供50范围内的随机数。对于您,将50替换为63或127