Thread: help with srand()

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    16

    help with srand()

    im writing a simple lotto simulator, not finished, but i when drawing the numbers they are all the same unless a lot of time goes by

    Im using srand() like this

    Code:
      srand(time(NULL));
      randnum = 1 + rand() % 25;
    But my code is executing so fast that im getting the same number, unless i do like 3000+ draws, then it will change the numbers a couple times

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(void) {
      int numBalls, numDraw;
      int randnum;
      
      printf("Enter number of Lottery Numbers to simulate:  ");
      scanf("%d", &numBalls);
      printf("Enter the number of lottery draws to simulate:  ");
      scanf("%d", &numDraw);
      
      int a, b;
      for (a = 0; a < numDraw; a++) {
        for (b = 0; b < numBalls; b++) {
          srand(time(NULL));
          randnum = 1 + rand() % 25;
          printf("%d\t", randnum);
          if (b == numBalls) {
            printf("\n");
          }
        }
      }
    }

  2. #2
    Learning C. JOZZY& Wakko's Avatar
    Join Date
    Nov 2009
    Posts
    59
    I have no experience in this but after looking around a bit I think you could use the sleep() function to achieve this by making the system wait for a certain time so the code does not execute that fast.

    The GNU C Library

    Maybe someone else has a better idea but this is the best I could come up with.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Take the srand() out of the loop.

    You should seed the random number generator *ONCE* and after that, leave it alone, and just have rand() inside the loop.

    And all will be well.

    Edit: You can NOT get a more random number, (as you're finding out), by seeding the random generator, multiple times. Instead, you can destroy the randomness of the numbers.

    Seed it once, and do it outside any loop.
    Last edited by Adak; 12-22-2009 at 08:51 AM.

  4. #4
    Learning C. JOZZY& Wakko's Avatar
    Join Date
    Nov 2009
    Posts
    59
    Quote Originally Posted by Adak View Post
    Take the srand() out of the loop.

    You should seed the random number generator *ONCE* and after that, leave it alone, and just have rand() inside the loop.

    And all will be well.

    Edit: You can NOT get a more random number, (as you're finding out), by seeding the random generator, multiple times. Instead, you can destroy the randomness of the numbers.

    Seed it once, and do it outside any loop.
    Just for my understanding do you mean that when putting the following code into the loop it sets the beginning value of rand() to the specified number each time again and this could result in the same number being drawn every time?
    Code:
    srand(time(NULL));
    Next to that I presume what I suggested is a go-around if it would work but would it work?

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Interesting.

    I guess this is because "the random number" is actually part of a sequence generated from the starting seed set by srand(). Everytime you call srand, you reinitialize this generation. So when you call srand() (with the same seed) then rand() repeatedly in sequence, you always get the same result.

    In fact a quick experiment demonstrates this:
    Code:
    #include <stdio.h>
    
    int main(void) {
    	int n, i, j;
    	for (i=0; i<10; i++) {
    		srand(2009);
    		for (j=0; j<5; j++) printf("%d ",rand());
    		printf("\n");
    	}
    }
    You get the exact same sequence of 5 different "random" numbers 10 times.

    As Adak (and the documentation) indicate, you are only supposed to call srand() once. However, you can do this repeatedly:
    Code:
    srand(rand());
    but there's no point. Also, using srand(rand()) once in the same program will result in exactly the same thing as not using srand() at all -- the program will generate the same sequence every time.

    That's why time() is a good choice -- you are unlikely to run the program more than once per second.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by JOZZY& Wakko View Post
    Just for my understanding do you mean that when putting the following code into the loop it sets the beginning value of rand() to the specified number each time again and this could result in the same number being drawn every time?
    Code:
    srand(time(NULL));
    Next to that I presume what I suggested is a go-around if it would work but would it work?
    Time is great to seed the random generator with, but ONLY DO IT ONCE, in your program.

    ONE seed is all you need. Do it early in the program, and don't use srand() again, in that program.

    Yes, if you seed the random generator with the same number (which is very easy to do inside a loop), you will keep re-setting the random number, and ruin the randomness, completely.

    You can't get a MORE random number than a good randomized number, and you better not try to do it. It is surprisingly difficult to get a REALLY good random number.

  7. #7
    Learning C. JOZZY& Wakko's Avatar
    Join Date
    Nov 2009
    Posts
    59
    Quote Originally Posted by MK27 View Post
    Interesting.
    but there's no point. Also, using srand(rand()) once in the same program will result in exactly the same thing as not using srand() at all -- the program will generate the same sequence every time.

    That's why time() is a good choice -- you are unlikely to run the program more than once per second.
    It is not my topic but I am trying to understand this here as well. You mean that setting a start point for srand() results in the same output every time because the random number is generated at the same moment in "time" after the starting point was given?

    How does srand(rand()) not solve this problem? Having a random staring point in my opinion would result in a different number then.

    And do you have a link that describes more of time() and it's uses in the C language? All I can find when searching for it with google are tutorials on how to use it in C++.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by JOZZY& Wakko
    How does srand(rand()) not solve this problem? Having a random staring point in my opinion would result in a different number then.
    That first call of rand() would always result in the same number on each run of the program since the generator is not seeded (or default seeded) at that point. As such, using this number to seed the generator does not provide any advantage over just using it unseeded (or default seeded). Since the seed is always the same on each run of the program, the generator sequence will always be the same on each run of the program.

    ~C_Student~ and JOZZY& Wakko, I suggest that you read Prelude's article on using rand().
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by JOZZY& Wakko View Post
    It is not my topic but I am trying to understand this here as well. You mean that setting a start point for srand() results in the same output every time because the random number is generated at the same moment in "time" after the starting point was given?
    I know next to nothing about random number generation, except that it is actually impossible to get a computer to generate a truly random number. The random number generator just spits out very unpredictable numbers.

    It seems pretty clear that what rand() effectively does is pull a number off the top of a sequence. What that sequence looks like is determined by the seed, and will probably differ from processor to processor (and maybe OS to OS).

    So, with that experiment from my last post, the sequence seeded by 2009 begins:

    1000717115 1824263957 1070373502 160509365 945947045

    as long as you DON'T call srand with the same value again, this random seeming sequence will continue -- each time you call rand(), you get a new value.

    However, if you start the program again OR call srand() with the same value, it just starts again:

    1000717115 1824263957 1070373502 160509365 945947045
    srand(2009)
    1000717115 1824263957 1070373502 160509365 945947045
    srand(2009)
    1000717115 1824263957 1070373502 160509365 945947045
    srand(2009)

    This is why srand(rand()) is ineffective. If no seed is set, rand uses 1 as the seed according to the ISO standard (??). So if you do this:
    Code:
    int main() {
          srand(rand());
          x = rand();
    }
    The first call to rand() has a seed of 1. The first time rand() is called with a particular seed, it will always generate the same number, so that program works exactly like this one:
    Code:
    int main() {
         x = rand();
    }
    Both of those, every time you run them, x will be the same.

    Which is why you can and should change the seed to a "random" value before you call rand(). Of course, you cannot get a truly random number on a computer. But time() returns the number of seconds since Jan 1, 1970, so it is never the same (there haven't been 4 billion seconds yet).

    And do you have a link that describes more of time() and it's uses in the C language? All I can find when searching for it with google are tutorials on how to use it in C++.
    I'm always on linux so I use either the GNU C library manual:
    Function Index - The GNU C Library
    or the POSIX specifications:
    The Open Group Base Specifications Issue 7
    the "alphabetical index" for the 2nd one is at the bottom.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by JOZZY& Wakko View Post
    It is not my topic but I am trying to understand this here as well. You mean that setting a start point for srand() results in the same output every time because the random number is generated at the same moment in "time" after the starting point was given?
    No. It's because the seed number from srand() is the same. If you use time, and the time is exactly the same when the program returns to the srand() line, then you'll get the same seed, and rand() will subsequently yield the same numbers it gave last time.


    How does srand(rand()) not solve this problem? Having a random staring point in my opinion would result in a different number then.
    because rand() by itself, will return only ONE SET of the random numbers that it can return. Instead of choosing different sets.

    And do you have a link that describes more of time() and it's uses in the C language? All I can find when searching for it with google are tutorials on how to use it in C++.
    My stuff is old, in books that have gone out of print, mostly. Not on the web, unfortunately.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The thing is that there are no random numbers in computers. Instead, what we usually do is take a initial number, called a seed, and apply an algorithm on this. So from that initial number, we get different numbers each time the algorithm runs. The first time, it always runs on the initial number that we set, the seed. Then it takes each random number it has generated and runs the algorithm on this.
    So, if you set the same seed every time, then you get the exact same random sequence.
    That is why you call srand once and only once. srand(rand()) might work theoretically but is pointless.

    Time is not difficult to use at all. It's the same in C and C++.
    Basically
    time_t mytime = time(NULL);

    No more difficult than that.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Use srand() twice in a function?
    By Jake.c in forum C Programming
    Replies: 5
    Last Post: 01-21-2009, 12:51 PM
  2. srand() in .Net
    By Sad Programmer in forum C++ Programming
    Replies: 6
    Last Post: 07-28-2003, 05:01 PM
  3. Same seed for srand yields different results
    By codegirl in forum C++ Programming
    Replies: 3
    Last Post: 06-23-2003, 02:39 PM
  4. When to srand()?
    By Imperito in forum C++ Programming
    Replies: 1
    Last Post: 05-12-2002, 12:20 AM
  5. srand()... possible reasons for failure
    By lightatdawn in forum C++ Programming
    Replies: 3
    Last Post: 12-18-2001, 02:33 AM