1

Below is a sample program I got to practice the use of the rand() function.

The weirdest thing is that every time the program is run, the first number generated by rand() (rand[0] in the program's output) is SIMILAR. It's not the same, but the number is always just slightly larger than the last time it was generated. rand[1-4] seem to be acceptably random however. Can anyone explain what is going on, and why??

Take a look at this sample output:

[paul@experimental C] $ ./a.out
rand[0]= 277735441                  <<<??????
rand[1]= 1417591956
rand[2]= 1284424674
rand[3]= 819876274
rand[4]= 1405457966
[paul@experimental C] $ ./a.out
rand[0]= 277769055                  <<<???????
rand[1]= 1982542454
rand[2]= 234757526
rand[3]= 642279943
rand[4]= 1546192179
[paul@experimental C] $ ./a.out
rand[0]= 277785862                  <<<??????? 
rand[1]= 117534056
rand[2]= 1857407599
rand[3]= 1627223601
rand[4]= 542817462

The source code:

 /*
     * rand: Generates 5 numbers using standard "srand()/rand()" function
     *
     * SAMPLE OUTPUT:
     *   rand[0]= 824522256
     *   rand[1]= 1360907941
     *   rand[2]= 1513675795
     *   rand[3]= 1046462087
     *   rand[4]= 253823980
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    int
    main (int argc, char *argv[])
    {
      /* Simple "srand()" seed: just use "time()" */
      unsigned int iseed = (unsigned int)time(0);
      srand (iseed);

      /* Now generate 5 pseudo-random numbers */
      int i;
      for (i=0; i<5; i++)
      {
        printf ("rand[%d]= %u\n",
          i, rand ());
      }
      return 0;
    }
1
  • 1
    rand is pretty crappy and broken. My understanding is that this is for a class or something. If, some day, you really need to use pseudorandom numbers, you should try to find another library.
    – zneak
    Commented Sep 14, 2011 at 23:01

4 Answers 4

4

A common implementation of srand leaves the first random number highly correlated to its seed. The standard makes no guarantees about how random the sequence must be.

3
  • so doing a rand after srand is adviced? Commented Sep 14, 2011 at 23:00
  • So after srand() is called I should 'throw-out' the first number generated by rand()?? Is rand() supposed to work this... err, poorly? Surely I'm doing something wrong. Commented Sep 14, 2011 at 23:01
  • 2
    @yi_H (and @Albert), I would think it's more advisable to not use rand altogether. The algorithm is widely recognized as crappy. Most platforms provide better solutions (like the random function, the /dev/random virtual device, etc.), and if you still can't find one, the Mersenne Twister library does a fairly good job.
    – zneak
    Commented Sep 14, 2011 at 23:03
0

rand returns a signed int. You're printing it as an unsigned value.

3
  • 1
    But rand is guaranteed to always return positive integers, so this shouldn't make any difference.
    – zneak
    Commented Sep 14, 2011 at 22:57
  • Same results if I print it as an int. Commented Sep 14, 2011 at 22:57
  • that doesn't explain the similarity of the first results of each.
    – fvu
    Commented Sep 14, 2011 at 22:59
0

Well basically rand() is a pseudo random generator. Since you're seeding using time(), that's probably the reason why the numbers are similar.

Try seeding using gettimeofday() multiplying tv_sec * tv_usec, or something similar.

0

Pseudo-random generators are never truly random, but based on a wide variety of mathematical algorithms. On my system, apparently a reasonably simple one is used, per the man pages:

static unsigned long next = 1;

    /* RAND_MAX assumed to be 32767 */
    int myrand(void) {
    next = next * 1103515245 + 12345;
        return((unsigned)(next/65536) % 32768);
    }

    void mysrand(unsigned seed) {
        next = seed;
    }

These type of random generators have been around for a while. If you are familiar with remainder arithmetic, then you see that you take a starting value, and twist and turn it with a remainder relative to 32768, and so get a value in the range promised by your machine. Nothing about this though is random. Your value produced is then used as a starting value for your next number.

In your case, you seed with the current time. If you run your program fast enough, you might even get the same value (that shouldn't happen, but it worked for me when I compiled your little program and ran it on my system). In any case, if you have one run fast after the other, you will likely see similar values - until you 'flip over' the remainder base.

Maybe read up on random number generation here:

http://en.wikipedia.org/wiki/Pseudorandom_number_generator

and it will make a little more sense.

Edit: If you wonder how people come up with the constants used to multiply your seed values, the quality of a pseudo-random generator is evaluated based on a number of criteria, such as, are the resulting values 'random looking' or 'clustered'. If you need seriously good pseudo-random numbers (probably not right now), you might want to implement your own.

Not the answer you're looking for? Browse other questions tagged or ask your own question.