-3

My program returns the same value every time I run it:

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

int main(void)
{
  int randomNum = rand() % 100;
  printf("random number: %d", randomNum);
}

Why is this and how can I fix it?

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
  • This is impossible to answer if you don't show the code you are using. Please [edit] your question and include it. Thank you! – Fabio says Reinstate Monica Feb 29 '20 at 22:43
  • It's called a pseudo-random number generator for a reason. – jwdonahue Feb 29 '20 at 22:43
  • A) When on Stack Overflow, please, **always show code for context**. B) The built-in `rand()` is pretty trash and has limitations. One of them is if you use `srand(time(NULL))` you will get the same series of numbers in any given second. C) If you didn't seed we don't know *because we can't see your code*. – tadman Feb 29 '20 at 22:43
  • I'll answer your question shortly, but please do take the [tour], read [ask] and [mcve]. – jwdonahue Feb 29 '20 at 22:44
  • 2
    Does this answer your question? [Why do I always get the same sequence of random numbers with rand()?](https://stackoverflow.com/questions/1108780/why-do-i-always-get-the-same-sequence-of-random-numbers-with-rand) – E_net4 Feb 29 '20 at 22:49
  • Right. As you probably already know by now, you're not seeding your random number generator using `srand()`. Note that you only need to do this once, and then you can obtain the next random number in the sequence with rand(); – Robert Harvey Feb 29 '20 at 22:49
  • 3
    This should have been closed as duplicate, not because it was off-topic. The OP barely had a chance to respond to criticism before it got closed. – jwdonahue Feb 29 '20 at 22:56

1 Answers1

2

That's because rand is a pseudo-random number generator, which means it returns the same sequence for any given input (the input is by default 1).

You can seed the random number generator with the time to get a different value each time you run your program:

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

int main(void)
{
    struct timespec ts;

    timespec_get(&ts, TIME_UTC);

    srand(ts.tv_sec ^ ts.tv_nsec);

    int random_num = rand() % 100;
    printf("random number: %d", random_num);
}

If you have POSIX you can also add a + getpid() to srand's argument and #include <stdlib.h>.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
  • @tadman Now it has the caveat that if run twice in the same nanosecond, or exactly a second later than the original invocation, it will produce identical results. – S.S. Anne Feb 29 '20 at 22:52
  • Thanks S.S. Anne – Chaouch Ghalem Feb 29 '20 at 22:57
  • I prefer the date and time myself. A simple hash of the date/time string is usually sufficient for any program in the current epoch. – jwdonahue Feb 29 '20 at 22:57
  • @ChaouchGhalem You can accept my answer by clicking the checkmark next to it to turn it green. – S.S. Anne Feb 29 '20 at 22:58
  • 1
    @jwdonahue Someone had to complain so I changed it. – S.S. Anne Feb 29 '20 at 22:58
  • Ya that's better ;). – jwdonahue Feb 29 '20 at 22:59
  • 1
    Although this is academic here, many systems have been cracked because someone didn't seed their random number generator properly. `srand(time(NULL))` has cost the industry at least millions of dollars in damages. It's worth pointing out the limitations of any approach taken, rather than declaring it "fixed". – tadman Feb 29 '20 at 22:59
  • 1
    Probably more like billions by now. – jwdonahue Feb 29 '20 at 23:00
  • And the saddest thing is, we don't really know where all the instances of that bug actually are. – jwdonahue Feb 29 '20 at 23:02
  • The C `rand()` function can't be made to work reliably. On some platforms it's so awful it has only 15 or 16 bits of entropy, it's truly useless. You're doing the best you can with the tools available, don't get me wrong, I'm just saying this thing has limitations and those need to be understood when employing it. C++ has a fantastic random number generation suite, but C is stuck using third-party libraries like OpenSSL etc. – tadman Feb 29 '20 at 23:04
  • The approaches you're suggesting here, like using nanosesconds or PIDs or some combination of all that, all suffer from the limitation that the seed itself is, at best, only 32-bits. When `rand()` was implemented it wasn't practical to enumerate all of these and check for patterns, but even on middling hardware now you can easily spin through all 2^32 combinations and find out which seed was used for any given sequence. It only takes a few seconds. `rand()` cannot be trusted when you need *actual* pseudo-random numbers, and not just randomish numbers. – tadman Feb 29 '20 at 23:07
  • @tadman Which, bear in mind, is not what the OP is asking for here. – S.S. Anne Feb 29 '20 at 23:08
  • Of course! I'm mostly pointing out that any effort to make `rand()` workable is wasted. It's best to leave it at `srand(ts.tv_sec ^ ts.tv_nsec)` and leave a caveat that `rand()` has some serious limitations. – tadman Feb 29 '20 at 23:11