Where is my mistake?

R

Red Dragon

I am self study C program student.
Hope someone can help me with this problem.
This program generates random numbers over a user defined range using call function
I used the call function " GenRndNum". The range is 2 and 10.
The problem is that I get the same 2 random numbers generated over 2 calls.
I should get 2 different random numbers. Can someone please point out my mistake?
Thanks
Khoon.


/* Generation of Random Numbers over a User Defined Range.*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int GenRndNum (int x, int y);

int main (void)

{
int MinRange;
int MaxRange;

int RndNum1;
int RndNum2;

printf ("Please key in the Minimum and Maximum Value for the Range of the two ");
printf ("\nrandom numbers> ");
scanf ( "%d %d", &MinRange, &MaxRange);
RndNum1= GenRndNum (MinRange, MaxRange);
printf ("RndNum1 = %d\n",RndNum1);

RndNum2= GenRndNum (MinRange, MaxRange);
printf ("RndNum2 = %d\n",RndNum2);

return 0;
}

int GenRndNum (int x, int y )

{ int z;
srand (time(NULL));
printf ("x = %d, y = %d\n",x,y);

z = rand() % ((y+1 ) - x ) + x;
printf ("z = %d\n",z);

return (z);
}


/*-----------------------
Result of Output:

Please key in the Minimum and Maximum Value for the Range of the two
random numbers> 2 10
x = 2, y = 10
z = 5
RndNum1 = 5
x = 2, y = 10
z = 5
RndNum2 = 5
Press any key to continue_
*/
 
S

Skarmander

Red said:
I am self study C program student.
Hope someone can help me with this problem.
<snip>

Please do not post HTML to Usenet. Many clients can't handle this and
even those who can have trouble converting it to text when replying.

You're using Outlook Express. To change the format, choose Tools ->
Options, click on the Send tab, and make sure the radio button "Plain
Text" is on for "News Sending Format".

Rest of the message ignored, sorry.

S.
 
E

Eric Sosman

Red said:
[...]
The problem is that I get the same 2 random numbers generated over 2 calls.
I should get 2 different random numbers. Can someone please point out my mistake?
[...]
int GenRndNum (int x, int y )

{ int z;
srand (time(NULL));

Here it is. See Question 13.17 in the comp.lang.c
Frequently Asked Questions (FAQ) list at

http://www.eskimo.com/~scs/C-faq/top.html

In fact, see all of Questions 13.15 through 13.20; there
are a few other problems with what you're doing, and the
FAQ can help you solve them.
 
O

orium69

you are using always the same srand value. try this:

long tm;
time(&tm);
srand(tm);
 
C

Christopher Benson-Manica

you are using always the same srand value. try this:

It is proper Usenet etiquette to include the relevant portions of the text
you are replying to. To do this using Google groups, please follow the
instructions below, penned by Keith Thompson:

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
E

Eric Sosman

you are using always the same srand value. try this:

Do NOT try this!
long tm;
time(&tm);
srand(tm);

Reason: The argument to time(), if non-NULL, must be
a pointer to a `time_t' object. `time_t' and `long'
are not necessarily the same thing. If you lie to
the compiler, it will get its revenge.
 
D

Dale

Red Dragon said:
I am self study C program student.
Hope someone can help me with this problem.
This program generates random numbers over a user defined range using
call function I used the call function " GenRndNum". The range is 2
and 10. The problem is that I get the same 2 random numbers generated
over 2 calls. I should get 2 different random numbers. Can someone
please point out my mistake? Thanks
Khoon.


/* Generation of Random Numbers over a User Defined Range.*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int GenRndNum (int x, int y);

int main (void)

{
int MinRange;
int MaxRange;

int RndNum1;
int RndNum2;

printf ("Please key in the Minimum and Maximum Value for the
Range of the two "); printf ("\nrandom numbers> ");
scanf ( "%d %d", &MinRange, &MaxRange);
RndNum1= GenRndNum (MinRange, MaxRange);
printf ("RndNum1 = %d\n",RndNum1);

RndNum2= GenRndNum (MinRange, MaxRange);
printf ("RndNum2 = %d\n",RndNum2);

return 0;
}

int GenRndNum (int x, int y )

{ int z;
srand (time(NULL));
printf ("x = %d, y = %d\n",x,y);

z = rand() % ((y+1 ) - x ) + x;
printf ("z = %d\n",z);

return (z);
}


/*-----------------------
Result of Output:

Please key in the Minimum and Maximum Value for the Range of the two
random numbers> 2 10
x = 2, y = 10
z = 5
RndNum1 = 5
x = 2, y = 10
z = 5
RndNum2 = 5
Press any key to continue_
*/

Less than a second passes between the two calls to time(), so it's
returning rhe same value to srand() each time.

One way to fix this would be to put a 1-second delay in between the calls
to GenRndNum. Some compilers support a sleep() function. If yours
doesn't, then this code will provide a 1-second delay:

time_t t;
t = time(NULL);
while(time(NULL) <= t);

Put it in GenRndNum(), right before the call to srand(). This will
guarantee that srand() will always get a different seed value.
 
A

Anonymous 7843

you are using always the same srand value. try this:

long tm; /* should be time_t as pointed out by another helpful person */
time(&tm);
srand(tm);

Aside from being wrong (as if this weren't enough) this
approach to seeding a random number generator opens up a
form of attack where two instances of the program are
started at the same time. One instance is used to observe
the seed, the second is manipulated by the user based on
his knowledge of the seed obtained from the first
instance.

For example, two instances of a card playing program
started at once would have the same sequence of cards
generated. The user could anticipate each card and play
the 2nd instance with complete knowledge of the cards
before they appear. In many card games this gives an
advantage.

There are many ways to solve this problem, however most of
them rely on OS-specific features. Of course, whatever you
do can be undone by a hacker willing to modify the program,
e.g. overwriting the call to srand() with a NO-OP
instruction.
 
B

Barry

Anonymous 7843 said:
Aside from being wrong (as if this weren't enough) this
approach to seeding a random number generator opens up a
form of attack where two instances of the program are
started at the same time. One instance is used to observe
the seed, the second is manipulated by the user based on
his knowledge of the seed obtained from the first
instance.

For example, two instances of a card playing program
started at once would have the same sequence of cards
generated. The user could anticipate each card and play
the 2nd instance with complete knowledge of the cards
before they appear. In many card games this gives an
advantage.

There are many ways to solve this problem, however most of
them rely on OS-specific features. Of course, whatever you
do can be undone by a hacker willing to modify the program,
e.g. overwriting the call to srand() with a NO-OP
instruction.

OT As all of this has been. If you have a system in which this is a
concern, you have much bigger security among other, concerns than a
pseudo-random number generator
 
K

Keith Thompson

Eric Sosman said:
Do NOT try this!


Reason: The argument to time(), if non-NULL, must be
a pointer to a `time_t' object. `time_t' and `long'
are not necessarily the same thing. If you lie to
the compiler, it will get its revenge.

This shouldn't be a case of lying to the compiler. If time_t happens
to be long, the code will work (though of course it's non-portable).
If time_t isn't long, the compiler *should* issue a diagnostic on the
call to time(), something like "passing arg 1 of `time' from
incompatible pointer type".
 
K

Kenneth Brody

Barry wrote:
[...]
Aside from being wrong (as if this weren't enough) this
approach to seeding a random number generator opens up a
form of attack where two instances of the program are
started at the same time. One instance is used to observe
the seed, the second is manipulated by the user based on
his knowledge of the seed obtained from the first
instance.

For example, two instances of a card playing program
started at once would have the same sequence of cards
generated. The user could anticipate each card and play
the 2nd instance with complete knowledge of the cards
before they appear. In many card games this gives an
advantage.
[...]

OT As all of this has been. If you have a system in which this is a
concern, you have much bigger security among other, concerns than a
pseudo-random number generator

And, for anyone who doubts that knowledge of a PRNG doesn't give someone
an advantage, search for "Ronald Harris".

http://www.brainboost.com/search.asp?Q=How+did+Ronald+Harris+cheat+at+keno?


Short version of the story:

Ronald Harris worked for the Las Vegas Gaming Commission, and was one of
the people who would verify the "honesty" of computer gaming machines.
(Such as the video poker machines all over the place.) He had access to
the source code for the Keno program used at Bally's Atlantic City, and
was able to create a program that, given a sequence of numbers generated
by the Keno computer, was able to give a pretty good guess as to the next
numbers to be picked. (This included the numbers for the _next_ game, as
well.)

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Keith Thompson

Keith Thompson said:
This shouldn't be a case of lying to the compiler. If time_t happens
to be long, the code will work (though of course it's non-portable).
If time_t isn't long, the compiler *should* issue a diagnostic on the
call to time(), something like "passing arg 1 of `time' from
incompatible pointer type".

More precisely, it is (conditionally) lying to the compiler, but the
compiler shouldn't be fooled (a diagnostic is required).
 
B

Barry

Kenneth Brody said:
Barry wrote:
[...]
long tm; /* should be time_t as pointed out by another helpful person */
time(&tm);
srand(tm);

Aside from being wrong (as if this weren't enough) this
approach to seeding a random number generator opens up a
form of attack where two instances of the program are
started at the same time. One instance is used to observe
the seed, the second is manipulated by the user based on
his knowledge of the seed obtained from the first
instance.

For example, two instances of a card playing program
started at once would have the same sequence of cards
generated. The user could anticipate each card and play
the 2nd instance with complete knowledge of the cards
before they appear. In many card games this gives an
advantage.
[...]

OT As all of this has been. If you have a system in which this is a
concern, you have much bigger security among other, concerns than a
pseudo-random number generator

And, for anyone who doubts that knowledge of a PRNG doesn't give someone
an advantage, search for "Ronald Harris".

http://www.brainboost.com/search.asp?Q=How+did+Ronald+Harris+cheat+at+keno?


Short version of the story:

Ronald Harris worked for the Las Vegas Gaming Commission, and was one of
the people who would verify the "honesty" of computer gaming machines.
(Such as the video poker machines all over the place.) He had access to
the source code for the Keno program used at Bally's Atlantic City, and
was able to create a program that, given a sequence of numbers generated
by the Keno computer, was able to give a pretty good guess as to the next
numbers to be picked. (This included the numbers for the _next_ game, as
well.)
An interesting read, thanks for the link.
Barry
 
R

Red Dragon

Skarmander said:
<snip>

Please do not post HTML to Usenet. Many clients can't handle this and even
those who can have trouble converting it to text when replying.

You're using Outlook Express. To change the format, choose Tools ->
Options, click on the Send tab, and make sure the radio button "Plain
Text" is on for "News Sending Format".

Rest of the message ignored, sorry.

S.

Thank you for your advice. Yes I am using Outlook Express. I did not know
I had caused a problem. Sorry for that.
Rgds,
Khoon.
 
R

Red Dragon

Eric Sosman said:
Red said:
[...]
The problem is that I get the same 2 random numbers generated over 2
calls.
I should get 2 different random numbers. Can someone please point out
my mistake?
[...]
int GenRndNum (int x, int y )

{ int z;
srand (time(NULL));

Here it is. See Question 13.17 in the comp.lang.c
Frequently Asked Questions (FAQ) list at

http://www.eskimo.com/~scs/C-faq/top.html

Thanks for your advice. Very useful and informative tips.
Rgds,
Khoon.
 
R

Red Dragon

Less than a second passes between the two calls to time(), so it's
returning rhe same value to srand() each time.

One way to fix this would be to put a 1-second delay in between the calls
to GenRndNum. Some compilers support a sleep() function. If yours
doesn't, then this code will provide a 1-second delay:

time_t t;
t = time(NULL);
while(time(NULL) <= t);

Put it in GenRndNum(), right before the call to srand(). This will
guarantee that srand() will always get a different seed value.

The strangest thing is that this problem only occurs when I do the
funcion call.
When I rewrite and did the random number generation inside the main
program itself, (and not utilising function call,) I did get two
different random nuimbers. So the problem due to time delay does not appear
to be the cause of the problem.

Rgds,
Khoon.
 
S

Steffen Buehler

You don't need to call srand() more than once in your program, anyway.
Once the seed is set, just call rand() as often as you need it - it will
create a series of (pseudo-)random numbers.
The strangest thing is that this problem only occurs when I do the
funcion call.
When I rewrite and did the random number generation inside the main
program itself, (and not utilising function call,) I did get two
different random nuimbers. So the problem due to time delay does not
appear to be the cause of the problem.

That's strange indeed. Did you call srand() here twice as well? And did
id happen each time? Maybe the system time really changed in between the
srand() calls.

Best regards
Steffen
 
R

Red Dragon

That's strange indeed. Did you call srand() here twice as well? And did
id happen each time? Maybe the system time really changed in between the
srand() calls.

Best regards
Steffen

Yes. Twice as well. In testing every time the rewritten program, I got 2
different random numbers.
No problem about it here. Here is the program. You can test it yourself.
The failure to generate different random numbers occurs only when I tried
function call.
I have set my Outlook Express to Skarmander's instruction, so hope you will
not be getting HTML format.
Thanks,
Khoon.

/* Generation of Random Numbers over a range.
13.10.05 */


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

int main (void)

{
int MinRange;
int MaxRange;

int RndNum1;
int RndNum2;

printf ("Please key in the Minimum and Maximum Value for the Range of the
two ");
printf ("random numbers>" );
scanf ( "%d %d", &MinRange, &MaxRange);

srand (time (NULL));

RndNum1 = rand() % ((MaxRange +1 ) - MinRange ) + MinRange;
RndNum2 = rand() % ((MaxRange +1 ) - MinRange ) + MinRange;

printf ("Two random numbers generated are %d & %d\n ", RndNum1,
RndNum2);

return 0;
}
 
K

Keith Thompson

Red Dragon said:
That's strange indeed. Did you call srand() here twice as well? And did
id happen each time? Maybe the system time really changed in between the
srand() calls.
[...]

Yes. Twice as well. In testing every time the rewritten program, I got 2
different random numbers.
No problem about it here. Here is the program. You can test it yourself.
The failure to generate different random numbers occurs only when I tried
function call. [...]

/* Generation of Random Numbers over a range.
13.10.05 */


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

int main (void)

{
int MinRange;
int MaxRange;

int RndNum1;
int RndNum2;

printf ("Please key in the Minimum and Maximum Value for the Range of the
two ");
printf ("random numbers>" );
scanf ( "%d %d", &MinRange, &MaxRange);

srand (time (NULL));

RndNum1 = rand() % ((MaxRange +1 ) - MinRange ) + MinRange;
RndNum2 = rand() % ((MaxRange +1 ) - MinRange ) + MinRange;

printf ("Two random numbers generated are %d & %d\n ", RndNum1,
RndNum2);

return 0;
}

In your original program, upthread, you call srand() withing
GenRndNum(), and you call GenRndNum() in main() -- thus two calls to
srand(). Since the value returned by time(NULL) is unlikely to change
between the two calls, it's not surprising that you'd get the same
"random" number twice. (It's also a bug; srand() should normally be
called only once in a given program, unless you're deliberately
recreating the same sequence multiple times.)

In the program you posted here, in spite of what you wrote above,
there's only one call to srand().

If you change your original program (the one with the GenRndNum()
function) so it calls srand() once in main(), rather than calling it
from GenRndNum(), it should do what you want.
 
R

Red Dragon

In your original program, upthread, you call srand() withing
GenRndNum(), and you call GenRndNum() in main() -- thus two calls to
srand(). Since the value returned by time(NULL) is unlikely to change
between the two calls, it's not surprising that you'd get the same
"random" number twice. (It's also a bug; srand() should normally be
called only once in a given program, unless you're deliberately
recreating the same sequence multiple times.)

In the program you posted here, in spite of what you wrote above,
there's only one call to srand().

If you change your original program (the one with the GenRndNum()
function) so it calls srand() once in main(), rather than calling it
from GenRndNum(), it should do what you want.


Good news.
Problem solved.
Earlier I did not understand the passing of data and wrote the program wrongly.
I have now discovered my error in the structure of the program writing.
Now I have rewritten and the program is working perfectly. I am getting 2 different random numbers each time now.

So the srand() seeding thing got blamed for nothing.

Here is my correct program.
Rgds,
Khoon.

/* Generation of Random Numbers over a User Defined Range with Function.
15.10.05 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void GenRndNum (int x, int y, int *RndNum1, int *RndNum2);
int main (void)

{
int MinRange;
int MaxRange;

int RndNum1;
int RndNum2;


printf ("Please key in the Minimum and Maximum Value for the Range of the two ");
printf ("\nrandom numbers> ");
scanf ( "%d %d", &MinRange, &MaxRange);
printf ( "MinRange =%d , MaxRange = %d\n", MinRange,MaxRange);


GenRndNum (MinRange, MaxRange, &RndNum1, &RndNum2);
printf ("RndNum1 = %d, RndNum2= %d\n",RndNum1,RndNum2);

return 0;
}
void GenRndNum (int x, int y, int *RndNum1,int *RndNum2)

{
srand (time (NULL));
*RndNum1 = rand() % ((y+1 ) - x ) + x;
*RndNum2 = rand() % ((y+1 ) - x ) + x;
return ;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,787
Messages
2,569,627
Members
45,328
Latest member
66Teonna9

Latest Threads

Top