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


当前回答

这是一个在你选择的两个数字之间得到一个随机数的好方法。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

    #define randnum(min, max) \
        ((rand() % (int)(((max) + 1) - (min))) + (min))

int main()
{
    srand(time(NULL));

    printf("%d\n", randnum(1, 70));
}

第一次输出:39

第二次输出:61

第三次输出:65

您可以将randnum后面的值更改为您选择的任何数字,它将在这两个数字之间为您生成一个随机数。

其他回答

在我最近的应用程序中,我遇到了一个严重的伪随机数生成器问题:我多次通过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是一个安全的赌注。

有人很好地解释了为什么使用rand()在给定范围内生成均匀分布的随机数是一个坏主意,我决定看看输出到底有多倾斜。我的测试案例是公平掷骰子。下面是C代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char *argv[])
{
    int i;
    int dice[6];

    for (i = 0; i < 6; i++) 
      dice[i] = 0;
    srand(time(NULL));

    const int TOTAL = 10000000;
    for (i = 0; i < TOTAL; i++)
      dice[(rand() % 6)] += 1;

    double pers = 0.0, tpers = 0.0;
    for (i = 0; i < 6; i++) {
      pers = (dice[i] * 100.0) / TOTAL;
      printf("\t%1d  %5.2f%%\n", dice[i], pers);
      tpers += pers;
    }
    printf("\ttotal:  %6.2f%%\n", tpers);
}

这是它的输出:

 $ gcc -o t3 t3.c
 $ ./t3 
        1666598  16.67%     
        1668630  16.69%
        1667682  16.68%
        1666049  16.66%
        1665948  16.66%
        1665093  16.65%
        total:  100.00%
 $ ./t3     
        1667634  16.68%
        1665914  16.66%
        1665542  16.66%
        1667828  16.68%
        1663649  16.64%
        1669433  16.69%
        total:  100.00%

我不知道你需要你的随机数有多统一,但上面的看起来足够统一,满足大多数需求。

编辑:用比time(NULL)更好的东西初始化PRNG是个好主意。

与此相关的特定于glibc的函数(应该在大多数Linux环境中都可以找到)是random(),或者您可能对其线程安全版本random_r()感兴趣。在将结构体random_data传递给random_r()之前,必须使用initstate_r()初始化它。

下面是一个快速的代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

void xxx (void) {
    unsigned int seed = (unsigned int) time(NULL);
    char rnd_state[17] = {0};
    struct random_data rnd_st_buf = {0};
    initstate_r(seed, &rnd_state[0], 17, &rnd_st_buf);
    for(size_t idx = 0; idx < 8; idx++) {
        int32_t rnd_int = 0;
        char rnd_seq_str[6] = {0};
        random_r(&rnd_st_buf, &rnd_int);
        memcpy((char *)&rnd_seq_str[0], (char *)&rnd_int, 4);
        printf("random number : 0x%08x,  \n", rnd_int);
    }
}

希望这比仅仅使用srand(time(NULL))更随机。

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    srand((unsigned int)**main + (unsigned int)&argc + (unsigned int)time(NULL));
    srand(rand());

    for (int i = 0; i < 10; i++)
        printf("%d\n", rand());
}

你也可以使用mathgl库#include <mgl2/mgl_cf.h>(虽然首先你需要安装它,我自己通过MSYS2安装)函数mgl_rnd()。它也有均匀分布,高斯分布等等。这是ez的用法。但我不知道它的特点。