The rand function in the loop

double rnd()
{
    srand(time(0));
    return(rand() % 1000 / 1000.0);
}

I call the function above in a loop, you need to make 1600 * 50000 scrolls. Everyone is familiar with the time() function, the loop runs many times more steps per second than 1. As a result, I get a bunch of identical numbers.

To solve my problem, I need to get a random number on each scroll (probability) some event.

Author: αλεχολυτ, 2014-05-16

2 answers

srand(time(0)); you need to call it once at the beginning. The randomness will be normal. A constant call to srand does not improve randomness.

Supplement

If you simplify these two functions very much (very much), the code will look like this somewhere:

int seed = 0; // это начальное значение генератора
int gen = 0; // начальное значения рандома
int magick = 1234567; // это такая специальная магическая константа, я ее сам придумал:)
     // а вообще то есть целые исследования, которые определяют правильные константы
     // того же Кнута почитать можно

void srand(int s) {
  seed = s;
}

int rand() {
  return func(gen, seed);
}

int func(int g, int s) {
  // эта функция на базе предыдущего значения вычисляет новое.
  // главное, что нужно понимать, что при одних и тех же значениях аргументов,
  // результат будет один и тот же.
  // реализация, приведенная ниже - это один с возможных вариантов.
  return (s * magick + g) % 0xFFFFFFFF;
}

The question arises - why is this done? It's very simple. It is quite difficult to make a fast and high-quality generator. Therefore, they take the simplest options. There is no point in complicating such generators - this makes them more complex. the quality will not improve, at best it will remain the same. But it usually only gets worse.

Another reason this is done is for the convenience of debugging. After all, seed defines the entire sequence. And if it is set to be the same, then rand will produce the same sequences.

If you need a really random sequence, then there are the following options:

  • buy a special device that will generate random numbers. Here's an example this is the USB token "iBank 2 Key" . The first thing that was found in Google:)
  • build such a device yourself - article on habr. There are a lot of interesting things there.
  • buy a special file with random numbers (yes, this is sold. I understand that many Linux fans will say, they say, I'm with /dev/random myself nageneryu, but the company promises good quality.
 12
Author: KoVadim, 2017-09-25 19:57:26

This is T. naz. "frequently occurring error".

If the program code contains multiple attempts to "restart" the pseudo-random number generator, using the current time value obtained by calling time(NULL) {[10 as the seed value]}

...
srand(time(NULL));
...

Then it may happen that such calls srand will follow each other very quickly. So fast that time(NULL) will return the same time value. This will cause the pseudo-random number generator to be constantly restart with the same seed value. As a result, subsequent calls to rand() will generate the same pseudo-random sequence.

For example, this code, when executed, will most likely output the same pseudo-random sequence twice

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

int main()
{
    srand(time(NULL));
    for (unsigned n = 20; n > 0; --n) 
      printf("%d ", rand());
    printf("\n");  

    srand(time(NULL));
    for (unsigned n = 20; n > 0; --n) 
      printf("%d ", rand());
    printf("\n");  
}

This problem is also sometimes reported in the following form: "Under the debagger, I get different random numbers in my program, and without the debagger, the same ones the same." Indeed, when a program is executed step by step in an interactive debugger, it is executed "slowly" and between calls srand the time value time(NULL) has time to change, which creates the illusion that everything works "as intended". But as soon as you run the program in free execution, the problem manifests itself in all its glory.

If you need to call srand(time(NULL)) in your program, then in most cases it is enough to do it only once at the start of the program.

 4
Author: AnT, 2017-09-25 20:22:25