有没有一个函数生成一个随机int数在C?或者我必须使用第三方库?


当前回答

<stdlib.h>中的rand()函数返回一个介于0和RAND_MAX之间的伪随机整数。你可以使用srand(unsigned int seed)来设置种子。

通常的做法是将%操作符与rand()结合使用以获得不同的范围(但请记住,这在一定程度上破坏了一致性)。例如:

/* random int between 0 and 19 */
int r = rand() % 20;

如果你真的在乎一致性,你可以这样做:

/* Returns an integer in the range [0, n).
 *
 * Uses rand(), and so is affected-by/affects the same seed.
 */
int randint(int n) {
  if ((n - 1) == RAND_MAX) {
    return rand();
  } else {
    // Supporting larger values for n would requires an even more
    // elaborate implementation that combines multiple calls to rand()
    assert (n <= RAND_MAX)

    // Chop off all of the values that would cause skew...
    int end = RAND_MAX / n; // truncate skew
    assert (end > 0);
    end *= n;

    // ... and ignore results from rand() that fall above that limit.
    // (Worst case the loop condition should succeed 50% of the time,
    // so we can expect to bail out of this loop pretty quickly.)
    int r;
    while ((r = rand()) >= end);

    return r % n;
  }
}

其他回答

我的极简解决方案应该适用于范围内的随机数[min, max)。在调用函数之前使用srand(time(NULL))。

int range_rand(int min_num, int max_num) {
    if (min_num >= max_num) {
        fprintf(stderr, "min_num is greater or equal than max_num!\n"); 
    }
    return min_num + (rand() % (max_num - min_num));
} 

对于c, STL不存在,你必须调用rand,或者更好的是,随机。它们在标准库头文件stdlib.h中声明。rand是POSIX, random是BSD规范函数。

rand和random之间的区别是random返回一个更有用的32位随机数,而rand通常返回一个16位数。BSD手册显示rand的较低位是循环的和可预测的,因此rand对于较小的数字可能是无用的。

在我最近的应用程序中,我遇到了一个严重的伪随机数生成器问题:我多次通过Python脚本调用我的C程序,并使用以下代码作为种子:

srand(time(NULL))

然而,由于:

Rand将生成相同的伪随机序列,在srand中给出相同的种子(参见man srand); 如前所述,time函数每秒只会变化:如果应用程序在同一秒内运行多次,time每次都会返回相同的值。

我的程序生成了相同的数字序列。 你可以做三件事来解决这个问题:

mix time output with some other information changing on runs (in my application, the output name): srand(time(NULL) | getHashOfString(outputName)) I used djb2 as my hash function. Increase time resolution. On my platform, clock_gettime was available, so I use it: #include<time.h> struct timespec nanos; clock_gettime(CLOCK_MONOTONIC, &nanos) srand(nanos.tv_nsec); Use both methods together: #include<time.h> struct timespec nanos; clock_gettime(CLOCK_MONOTONIC, &nanos) srand(nanos.tv_nsec | getHashOfString(outputName));

选项3确保了你(据我所知)最好的种子随机性,但它可能只会在非常快速的应用中产生差异。 在我看来,选择2是一个安全的赌注。

#include <stdio.h>
#include <dos.h>

int random(int range);

int main(void)
{
    printf("%d", random(10));
    return 0;
}

int random(int range)
{
    struct time t;
    int r;

    gettime(&t);
    r = t.ti_sec % range;
    return r;
}

如果您需要比stdlib提供的质量更好的伪随机数,请检查Mersenne Twister。它也更快。示例实现有很多,例如这里。