Menu

rand() not so random (WinXP)

2004-03-18
2012-09-26
  • Nobody/Anonymous

    Hi,

    Trying to get rid of Borland randomize()/random(), I (with help from Google and this forum) managed to write this:

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

    #define DIVIDE RAND_MAX

    int i;

    int main(void)
    {
        srand((unsigned) time(NULL));
       
        printf("The first \&quot;pseudo-random\&quot; number is: ");
        printf("%d\n", (int) (100.0*rand()/(DIVIDE+1.0)) );
        printf("Next numbers are:");
        for (i=1; i<=7; i++)
            printf(" %d ", (int) (100.0*rand()/(DIVIDE+1.0)) );
       
        printf("\n\n\n\n");
        system("PAUSE");
        return(0);
    }
    ----------------------------------

    BUT the first pseudo-random number is quite always the same from one run to another. It slowly evolve from n to n+1 from time to time ...
    The following numbers obtained with rand() are just fine.

    Replacing 'RAND_MAX' by a small constant like 1, I see where the problem come from: say at #1 run I get 743800, I'll get 744000 at #2 run

    I get no such problem under Linux (except output of printf, just replacing RAND_MAX by RAND_MAX/1000 and not 1 is OK).

    I know older versions of Windows had serious problems with pseudo-random numbers and that they could even be guessed after a few tries with net hacks, but thought that it was fixed with Win2k and later.

    Is this where the problem comes from? Or from a lib that isn't the same in Dev-C++/gcc and Linux/gcc? Or a problem with 'higher/lower bits' used by srand/rand (don't think so)?
    Or am I far from the solution? :-D

    Is there a better function under Windows or should I consider writing a small 'rand2' function that should diverge with quite similar seeds?

    Using: WinXP Home and Dev-C++ 4.9.8.0
    Log: just fine (and in French)
    Compilateur: Default compiler
    Excution de  gcc.exe...
    gcc.exe "C:\Documents and Settings\Jacques\Bureau\random3.c" -o "C:\Documents and Settings\Jacques\Bureau\random3.exe"   -g3  -I"C:\Dev-Cpp\include"   -L"C:\Dev-Cpp\lib"
    Excution termine
    Compilation OK

    Thanks in advance,
    Jacques

     
    • qWake

      qWake - 2004-03-18

      Your approach to generating random numbers in the range [0,99] makes use of the higher bits of the value returned by rand().  A more common approach is to use rand()%100, which uses the lower bits of the value instead.  Why is this relevant?  Because the call to srand(time(0)) seeds the current time, and so the high bits will remain similar for two consecutive runs, giving you the results you are getting.

      To see this more clearly, print the floating point value in full.  Try this main function and run the program a few times, it will make the difference clear:

      int main() {
      int first;
      srand(time(0));
      first = rand();
      printf("First: %d -- %f -- %d\n", first, 100.0 * first / (1.0 + RAND_MAX), first % 100);
      system("PAUSE");
      return(0);
      }

      qWake

       
    • Wayne Keen

      Wayne Keen - 2004-03-19

      Jacques,

      I noticed something having nothing whatsoever to do with random number properties, but not unimportant.  Looking where your file you are compiling is:

      C:\Documents and Settings\Jacques\Bureau\random3.c

      I see you have put it in a directory with spaces in the path.  You can get away with this for compiuling a single file, but eventually, it will bite you when you compile a project.  Avoid spaces. *Please*

      :-)

      Wayne

       
    • Jim W.

      Jim W. - 2004-03-19

      There are many relatively simple ways to "fake up" some "noise" for input into a randomizing scheme.  One of the "cheapest" is user input, if the program can work that way.

      There's a great deal of literature on the topic.  Try a Google search on some key terms....

      -- Jim.

       
    • aditsu

      aditsu - 2004-03-19

      the random number generation doesn't come from Windows but from the msvcrt library (which mingw uses, in all win32 versions); for me, the greatest defect it has is the small RAND_MAX
      but you are also right: when you seed the generator, the first rand is too dependent on the seed
      one solution is to call rand once or twice after srand, without using the values:

      srand((unsigned) time(NULL)); //or shortly: srand(time(0));
      rand();
      rand();
      and then you can do what you want

      there are some random generators whose lower bits are "less random" (and in that case, you have to use the higher bits), but I think the one in msvcrt is not of that kind
      if you want to know more about generating random numbers, read Knuth (The Art of Programming) vol. 2

      Adrian

       
    • Amanda Wee

      Amanda Wee - 2004-03-20

      Incidentally, you might want to try out an implementation of the Mersenne Twister pseudo-random number algorithm from here:
      http://www-personal.engin.umich.edu/~wagnerr/MersenneTwister.html

       
    • Wayne Keen

      Wayne Keen - 2004-03-20

      For some purposes, I use the Gnu Scientific Library (GSL) of random numbers.  It has a large number of random distributions available.  If you search the forum, you should find a couple of places where I talk about how to find it and set it up.

      Wayne

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.