0

I want to create a number between 1-10000.

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

int main() {

    int numb;
    srand(time(NULL));

    numb = (rand()%9999)+1;

    printf("%d", numb);

}

But for some reason, it generates the numbers so slowly. I mean, let's say I ran the program. It gives me a "1145" after a second, I ran it again and it says "1151"... 5 seconds later, it says "1211"

as you can see, they are really close numbers. I want it to change so fast. If I use it 5 times in 5 seconds, I want numbers like 49, 1124, 6665, 9000, 140 etc...

What can I do to make this happen? Sorry for English and thanks in advance...

danglingpointer
  • 4,708
  • 3
  • 24
  • 42
blackwater7
  • 107
  • 1
  • 9
  • 7
    When we talk about randomness, there is not "close number". "9, 9, 9, 9, 9" is a perfect random suite of number. http://dilbert.com/strip/2001-10-25 – Tom's Mar 05 '18 at 13:40
  • Maybe the system you are running the program on is causing the issue. You can run the code on https://www.onlinegdb.com/ and see that the code is not causing it. – Jos Mar 05 '18 at 13:52
  • It should work fine if you have a decent implementation of `srand()`/`rand()` on your system. I tried the code in Linux with gcc and I got a seemingly random sequence. – Klas Lindbäck Mar 05 '18 at 13:55
  • 1
    Possible duplicate of [Is there an alternative to using time to seed a random number generation?](https://stackoverflow.com/questions/7617587/is-there-an-alternative-to-using-time-to-seed-a-random-number-generation) – vgru Mar 05 '18 at 14:25
  • Also, this: [Equivalent of /dev/urandom on Windows](https://stackoverflow.com/q/22049203/69809). `rand()` in Windows is rather crappy. – vgru Mar 05 '18 at 14:27
  • 1
    It is better to use the top bits of `rand()` rather than the bottom bits, for example by `do numb = (rand() / (RAND_MAX / 10000)) + 1; while (numb > 10000);`. The `do ... while` loop is to eliminate a few out of range `rand()` values and to remove bias. By the way, your `%9999` will only give you 9999 different numbers. You should have used `%10000` to get 10000 different numbers. – Ian Abbott Mar 05 '18 at 14:55
  • Possible duplicate of [srand() — why call it only once?](https://stackoverflow.com/questions/7343833/srand-why-call-it-only-once) – pjs Mar 05 '18 at 22:10

3 Answers3

4

The C random number generator is not designed to be re-seeded repeatedly, and seeding to the clock time will probably generate the same sequence for at last a second or so.

Essentially you need to keep the generator process up and running so you don't need to re-seed it.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

If your program is liable to be run more than once per second, you'll need to seed the random number generator with something other than the system clock. For example, you could fetch a few bytes from /dev/urandom as follows:

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

int main() {
    int s, numb;
    FILE *f;

    f = fopen("/dev/urandom", "rb");
    fread(&s, sizeof(int), 1, f);
    fclose(f);
    srand(s);

    numb = rand() % 9999 + 1;
    printf("%d\n", numb);
    return 0;
}

Bear in mind, however, that many implementations of rand() are quite easy to predict based on just a few consecutive output values. There are better alternatives available (e.g., arc4random()).

r3mainer
  • 23,981
  • 3
  • 51
  • 88
1

As you know, within the same second, time(NULL) returns the same value, so if you call your program multiple times in one second, your output won't change at all.

If you call your program once and then once again one second later, the output of time(NULL) will increase by one. Now, you might hope that any difference in the value you hand to srand() would yield an arbitrarily large difference in the return value of the next call to rand(). In fact, I would hope this, too, but just recently on one of my systems (I forget which) I was disappointed to discover that this was not the case. Small changes in the value passed to srand() yielded small values in the next value returned by rand().

There are several things you can do about this:

  1. Use a "truly" random seed, perhaps one read from /dev/random.
  2. "Mix up" the seed a little. On Unix systems, a popular technique is to call srand(time(NULL) ^ getpid()).
  3. Throw away the first few values from rand().
  4. Use the high-order bits of the values returned by rand(), not the low-order ones. For example, as suggested by the C FAQ list, instead of rand() % N, use rand() / (RAND_MAX / N + 1).
Steve Summit
  • 45,437
  • 7
  • 70
  • 103