tags:

views:

1323

answers:

12

this is the first time i m trying random numbers with c (i miss c#) here is my code

int i , j= 0;
for(i=0;i<=10;i++){
j = rand();
printf("j = %d\n",j);
}

with this code i get the same sequance everytime the code but it generates random sequences if i add srand(/*somevalue/*) before the for loop . can someone explain why ?

+14  A: 

You have to seed it. Seeding it with the time is a good idea:

srand();

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

int main ()
{
  srand ( time(NULL) );
  printf ("Random Number: %d\n", rand() %100);
  return 0;
}

You get the same sequence because rand() is automatically seeded with the a value of 1 if you do not call srand().

Edit

Due to comments

rand() will return a number between 0 and RAND_MAX (defined in the standard library). Using the modulo operator (%) gives the remainder of the division rand()/100. This will force the random number to be within the range 0-99. For example, to get a random number in the range of 0-999 we would apply rand()/1000.

kjfletch
i already know this but my question is why does it give the same sequance when i dont use srand ?
Yassir
Because if you don't seed it manually, it is ***ALWAYS*** seeded to 1 by default. See Aditya's answer.
GMan
If security is a concern, seeding it with the time is a rather bad idea, as an attacker can often find or guess the startup time relatively easily (within a few dozen to a few hundred attempts), then replay your sequence of pseudorandom numbers. If possible, try to make use of an operating-system-provided entropy source for your seed instead.
Dave Sherohman
If security is a concern, using rand() at all is a rather bad idea, no matter how you seed it. Aside from the unknown strength of the PRNG algorithm, it generally only takes 32 bits of seed, so brute forcing is plausible even if you don't make it extra-easy by seeding with the time. Seeding rand() with an entropy source for security is like giving a donkey steroids and entering it in the [Kentucky] Derby.
Steve Jessop
why is there a %100 after printf()?
fahad
+14  A: 

To quote from man rand :

The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand(). These sequences are repeatable by calling srand() with the same seed value.

If no seed value is provided, the rand() function is automatically seeded with a value of 1.

So, with no seed value, rand() assumes the seed as 1 (every time in your case) and with the same seed value, rand() will produce the same sequence of numbers.

Aditya Sehgal
@matthew : From your link , "If rand() is called before any calls to srand() are made, the same sequence shall be generated as when srand() is first called with a seed value of 1."
Aditya Sehgal
Thanks, Aditya. My mistake for skimming too fast.
Matthew Flaschen
A: 

call srand(sameSeed) before calling rand(). More details here.

dfa
A: 

Seeding the rand()

void srand (unsigned int seed)

This function establishes seed as the seed for a new series of pseudo-random numbers. If you call rand before a seed has been established with srand, it uses the value 1 as a default seed.

To produce a different pseudo-random series each time your program is run, do srand (time (0))

nik
A: 

This is from http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.13.html#rand:

Declaration:

void srand(unsigned int seed);

This function seeds the random number generator used by the function rand. Seeding srand with the same seed will cause rand to return the same sequence of pseudo-random numbers. If srand is not called, rand acts as if srand(1) has been called.

Key
+4  A: 

Random number generators are not actually random, they like most software is completely predictable. What rand does is create a different pseudo-random number each time it is called One which appears to be random. In order to use it properly you need to give it a different starting point.

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

int main ()
{
  /* initialize random seed: */
  srand ( time(NULL) );

  printf("random number %d\n",rand());
  printf("random number %d\n",rand());
  printf("random number %d\n",rand());
  printf("random number %d\n",rand());

  return 0;
}
Howard May
+1  A: 

rand() returns the next (pseudo) random number in a series. What's happening is you have the same series each time its run (default '1'). To seed a new series, you have to call srand() before you start calling rand().

If you want something random every time, you might try:

srand (time (0));
Chet
+14  A: 

rand() returns pseudo-random numbers. It generates numbers based on a given algorithm. The starting point of that algorithm is always the same, so you'll see the same sequence generated for each invocation. This is handy when you need to verify the behavior and consistency of your program.

You can set the "seed" of the random generator with the srand function(only call srand once in a program) One common way to get different sequences from the rand() generator is to set the seed to the current time or the id of the process:

srand(time(NULL)); or srand(getpid()); at the start of the program.

Generating real randomness is very very hard for a computer, but for practical non-crypto related work, an algorithm that tries to evenly distribute the generated sequences works fine.

nos
+1, especially for mentioning that it's no good for cryptographic needs.
DevSolar
+1, for mentioning that it's actually a pseudo-random number generator and that is why is always gives out the same numbers with the same starting seed value.
Matt H
+6  A: 

If I remember the quote from Knuth's seminal work "The Art of Computer Programming" at the beginning of the chapter on Random Number Generation, it goes like this:

"Anyone who attempts to generate random numbers by mathematical means is, technically speaking, in a state of sin".

Simply put, the stock random number generators are algorithms, mathematical and 100% predictable. This is actually a good thing in a lot of situations, where a repeatable sequence of "random" numbers is desirable - for example for certain statistical exercises, where you don't want the "wobble" in results that truly random data introduces thanks to clustering effects.

Although grabbing bits of "random" data from the computer's hardware is a popular second alternative, it's not truly random either - although the more complex the operating environment, the more possibilities for randomness - or at least unpredictability.

Truly random data generators tend to look to outside sources. Radioactive decay is a favorite, as is the behavior of quasars. Anything whose roots are in quantum effects is effectively random - much to Einstein's annoyance.

Tim H
+2  A: 

There's a lot of answers here, but no-one seems to have really explained why it is that rand() always generates the same sequence given the same seed - or even what the seed is really doing. So here goes.

The rand() function maintains an internal state. Conceptually, you could think of this as a global variable of some type called rand_state. Each time you call rand(), it does two things. It uses the existing state to calculate a new state, and it uses the new state to calculate a number to return to you:

state_t rand_state = INITIAL_STATE;

state_t calculate_next_state(state_t s);
int calculate_return_value(state_t s);

int rand(void)
{
    rand_state = calculate_next_state(rand_state);
    return calculate_return_value(rand_state);
}

Now you can see that each time you call rand(), it's going to make rand_state move one step along a pre-determined path. The random values you see are just based on where you are along that path, so they're going to follow a pre-determined sequence too.

Now here's where srand() comes in. It lets you jump to a different point on the path:

state_t generate_random_state(unsigned int seed);

void srand(unsigned int seed)
{
    rand_state = generate_random_state(seed);
}

The exact details of state_t, calculate_next_state(), calculate_return_value() and generate_random_state() can vary from platform to platform, but they're usually quite simple.

You can see from this that every time your program starts, rand_state is going to start off at INITIAL_STATE (which is equivalent to generate_random_state(1)) - which is why you always get the same sequence if you don't use srand().

caf
+2  A: 

None of you guys are answering his question.

with this code i get the same sequance everytime the code but it generates random sequences if i add srand(/somevalue/) before the for loop . can someone explain why ?

From what my professor has told me, it is used if you want to make sure your code is running properly and to see if there is something wrong or if you can change something.

James
His question has already been answered before, if you read through the answers properly. What your professor told you is just a inference of why the rand() algorithm was programmed the intended way.
Manav MN
A: 

BTW: The fact that rand is NOT random (PRNG = PSEUDO Random Number Generator, where pseudo is the key word!) can be very useful.

If the same algorithm is used on computers across a network, and if some data (eg game state) is calculated using 'random' numbers, and if the code on all machines is synced such that the rand call is called in the same place/time by all clients, then you can reduce network load by regenerating data/events/whatever locally.

Pseudo-random is a lovely thing. :)


PS If you ever rely on rand(om) being syncronized, however, you should code your own implementation -- else platform and other differences will spoil your fun. :)

fullreset