tags:

views:

267

answers:

9

I know this question has been asked time and again. I need random numbers between 0-9. I am using the following code:

srand(time());
int r;
for (;;)
{
    while(condition)
    {
        r = rand()%10;
        // ...
        // ...
    }
}

Now I am getting the same sequence of numbers for each iteration of for loop. Can someone provide me the correct code?

PS - My compiler doesn't recognize arcrandom().

+7  A: 

You're probably calling this function within the second, and srand is going to get seeded with the same second. You should only call srand once at the beginning of main.

Bruce
A solution might be to use another seed source, such as a higher resolution timer.
RaphaelSP
In the code `srand` is called only once and not inside the loop. That does not make the sequence repeat every iteration
Martinho Fernandes
Martinho, you know this how? It's called once *inside the function it resides*, which may or may not be `main()`.
GMan
@GMan: it's not called *inside* the loop, so it won't repeat every *iteration*
Martinho Fernandes
You're correct. But you made the claim "srand is called only once", which can't be determined from his code. Consider: `void foo() {/* his code */} int main() {while (true) foo() }`
GMan
Okay, the only once assertion was a little unfortunate. I meant only once withing the context of the code posted, and not once during the application lifetime.
Martinho Fernandes
I mean, Bruce is still correct to say `srand` should be called only once at the beginning of main. Otherwise problems will arise. It just won't cause the problem posed here.
Martinho Fernandes
A: 
srand(time(0));

r = rand() % (max+1);

//r will be a random number between 0 and max.

I can only think that you did not initialize correctly, or your redacted code is redacted wrongly.

Paul Nathan
Oops! `rand() % max+1` is different than `rand() % (max+1)`.
pmg
Durrr! That's what comes of fast typing.
Paul Nathan
The irony is "or your redacted code is redacted wrongly."
Martinho Fernandes
A: 

Your code doesn't compile -- for() is not valid C.

Are you sure that you are calling srand only once, at the start of the program and before any rand calls? Calling srand within the loop would explain this behavior.

ephemient
The for loop has a condition inside it.It is not relevant to my question...Yes I am calling srand() only once, before any rand calls
Bruce
@Peter: if it is not relevant, you can write it as `for(;;)` which is valid and won't upset anyone.
Martinho Fernandes
My bad..I didn't mean to upset you
Bruce
+13  A: 

This problem stems from the fact that on some implementations the lower-order bits of rand() are not very random. Quoting from the man page:

"If you want to generate a random integer between 1 and 10, you should always do it by using high-order bits, as in

j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));

and never by anything resembling

j = 1 + (rand() % 10);

(which uses lower-order bits)."

Martinho Fernandes
I have tried it before..It doesn't work
Bruce
@Peter: Well, I can't help you then... You're probably doing something else wrong that you didn't notice and didn't copy into the example code you posted. There seems to be nothing else wrong with it.
Martinho Fernandes
You're probably right Martinho. I will look at my code again. Thank you for the answer
Bruce
Are you calling srand once, and only once at application startup ? do not call srand more than once.
nos
A: 

Have you random()?

random() man page

I have made simple program:

int i;
for(i=0;i<40;i++)
printf("%d",rand()%10);

And geting 7938024839052273790239970398657627039991 - no repeating here. How long is your sequence?

Malx
+1  A: 

Remove all srand() calls from your code.

Add one, unique call right before the first statement in main().

int main(void) {
    int foo = 42;
    int bar = baz(42);

    srand(time(0));
    /* rest of your program */
    return 0;
}
pmg
+2  A: 

Many pseudorandom generators have an observable period.
If you need a long period consider using the algorithm from Knuth 2. It has a period of about 2^55, and is simple to implement.
RANARRAY

EvilTeach
The lower-order bits of rand() do have a short period. But the OP says that working around that doesn't solve the problem...
Martinho Fernandes
A: 

The only possible way you could be getting the exact same sequence of numbers is if there is a call to srand() somewhere in the code that you haven't shown us. It could be deep within a function call somewhere.

The proper way to fix this would be to find the extra call to srand and remove it. However this quick hack might get you started:

static int seed = time();
int r;
for (;;)
{
    srand(seed++);
    while(condition)
    {
        r = rand()%10;
        // ...
        // ...
    }
}
Mark Ransom
A: 

Depending on your requirements for statistical randomness you might find it better to ditch the psuedo random number generator and try an external source.

random.org and randomnumbers.info (amongst others) will provide truly random numbers for download, which libcurl should handle for you.

Andrew Edgecombe