使用rand生成随机数

时间:2021-10-16 22:51:44

gcc 4.4.4 c89

gcc 4.4.4 c89

I am using the code below. However, I keep getting the same number:

我正在使用下面的代码。但是,我一直得到相同的数字:

    size_t i = 0;

    for(i = 0; i < 3; i++) {
        /* Initialize random number */
        srand((unsigned int)time(NULL));
        /* Added random number (simulate seconds) */
        add((rand() % 30) + 1);
    }

I would like to get 0 to 30 returned. However, the last time I ran this I got 17 three times.

我想回到0到30。但是,我最后一次跑这个三次得了17次。

Many thanks,

6 个解决方案

#1


22  

You're seeding inside the loop (with the same value because of how quickly the loop will be executed), which causes the random number generated to be the same each time.

你在循环内播种(由于循环的执行速度有相同的值),这导致每次生成的随机数相同。

You need to move your seed function outside the loop:

您需要在循环外移动种子函数:

/* Initialize random number */
srand((unsigned int)time(NULL));

for(i = 0; i < 3; i++) {
    /* Added random number (simulate seconds) */
    add((rand() % 30) + 1);
}

#2


9  

You need to call srand just once, at the beginning of your program.

你需要在程序开始时只调用一次srand。

srand initializes the pseudo random number generator using time in seconds. If you initialize it with a particular number, you will always get the same sequence of numbers. That's why you usually want to initialize it at the beginning using the time (so that the seed is different each time you run the program) and then use only rand to generate numbers which seem random.

srand使用时间以秒为单位初始化伪随机数生成器。如果使用特定数字对其进行初始化,则始终会获得相同的数字序列。这就是为什么你通常想要在开始时使用时间初始化它(这样每次运行程序时种子都不同)然后只使用rand来生成看似随机的数字。

In your case the time does not change from iteration to iteration, as its resolution is just 1 second, so you are always getting the first number of the pseudo-random sequence, which is always the same.

在你的情况下,时间不会从迭代变为迭代,因为它的分辨率只有1秒,所以你总是得到伪随机序列的第一个数字,它始终是相同的。

#3


4  

You need to do srand((unsigned int)time(NULL)) only once before the loop.

你需要在循环之前只做一次srand((unsigned int)time(NULL))。

#4


2  

It is completely possible that the 3 times 17 are still completely random.

完全有可能3次17仍然是完全随机的。

There is an about 1 in 10 chance of getting two numbers the same when using a range of 1-30 and three picks. (this is due to the birthday problem )

当使用1-30和三个选择范围时,有大约十分之一的机会让两个数字相同。 (这是由于生日问题)

Now, getting three the same results has still a propability of 1 in 900 using the same range.

现在,使用相同的范围得到三个相同的结果仍然可以在900中使用1。

you might want to read more background on the analysis page of random.org

您可能想在random.org的分析页面上阅读更多背景信息

#5


1  

Seed to the pseudo Random number generator should be called only once outside the loop. Using time as a seed is good thing. However there is still a possiblity of getting the same random number.

种子到伪随机数生成器只应在循环外调用一次。用时间作为种子是好事。然而,仍然有可能获得相同的随机数。

#6


1  

I rather suggest also using gettimeofday() system call to retrieve the seed to be used to feed srand().

我建议还使用gettimeofday()系统调用来检索用于提供srand()的种子。

Something like


struct timeval tv;
...
gettimeofday(&tv, NULL);
srand(tv.tv_usec);
...

This approach can add more entropy in your pseudo number generation code. IMHO of course

这种方法可以在伪数生成代码中添加更多熵。恕我直言

Ciao ciao

#1


22  

You're seeding inside the loop (with the same value because of how quickly the loop will be executed), which causes the random number generated to be the same each time.

你在循环内播种(由于循环的执行速度有相同的值),这导致每次生成的随机数相同。

You need to move your seed function outside the loop:

您需要在循环外移动种子函数:

/* Initialize random number */
srand((unsigned int)time(NULL));

for(i = 0; i < 3; i++) {
    /* Added random number (simulate seconds) */
    add((rand() % 30) + 1);
}

#2


9  

You need to call srand just once, at the beginning of your program.

你需要在程序开始时只调用一次srand。

srand initializes the pseudo random number generator using time in seconds. If you initialize it with a particular number, you will always get the same sequence of numbers. That's why you usually want to initialize it at the beginning using the time (so that the seed is different each time you run the program) and then use only rand to generate numbers which seem random.

srand使用时间以秒为单位初始化伪随机数生成器。如果使用特定数字对其进行初始化,则始终会获得相同的数字序列。这就是为什么你通常想要在开始时使用时间初始化它(这样每次运行程序时种子都不同)然后只使用rand来生成看似随机的数字。

In your case the time does not change from iteration to iteration, as its resolution is just 1 second, so you are always getting the first number of the pseudo-random sequence, which is always the same.

在你的情况下,时间不会从迭代变为迭代,因为它的分辨率只有1秒,所以你总是得到伪随机序列的第一个数字,它始终是相同的。

#3


4  

You need to do srand((unsigned int)time(NULL)) only once before the loop.

你需要在循环之前只做一次srand((unsigned int)time(NULL))。

#4


2  

It is completely possible that the 3 times 17 are still completely random.

完全有可能3次17仍然是完全随机的。

There is an about 1 in 10 chance of getting two numbers the same when using a range of 1-30 and three picks. (this is due to the birthday problem )

当使用1-30和三个选择范围时,有大约十分之一的机会让两个数字相同。 (这是由于生日问题)

Now, getting three the same results has still a propability of 1 in 900 using the same range.

现在,使用相同的范围得到三个相同的结果仍然可以在900中使用1。

you might want to read more background on the analysis page of random.org

您可能想在random.org的分析页面上阅读更多背景信息

#5


1  

Seed to the pseudo Random number generator should be called only once outside the loop. Using time as a seed is good thing. However there is still a possiblity of getting the same random number.

种子到伪随机数生成器只应在循环外调用一次。用时间作为种子是好事。然而,仍然有可能获得相同的随机数。

#6


1  

I rather suggest also using gettimeofday() system call to retrieve the seed to be used to feed srand().

我建议还使用gettimeofday()系统调用来检索用于提供srand()的种子。

Something like


struct timeval tv;
...
gettimeofday(&tv, NULL);
srand(tv.tv_usec);
...

This approach can add more entropy in your pseudo number generation code. IMHO of course

这种方法可以在伪数生成代码中添加更多熵。恕我直言

Ciao ciao