Difference in behaviour of rand() function in C [duplicate] - c

This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 5 years ago.
I am trying to implement multiply-shift algorithm for hashing and need to generate a new random number every time. I used a function to do the same as follows-
long mulShift(long x)
// returns h(x) for multiply shift function
{
srand (time (NULL));
long a = rand() % (long)pow(2,u);
if ((a>>1)<<1 == a)
a = a + 1;
long h = ((a*x) >> (u-k));
printf("%ld\t%ld\n", x, a);
return h%m;
}
Here u and k are global variables. If I call this function in a loop as follows-
for (int i = 0; i<5; i++)
mulShift(15);
I get the following output-
15 528638629
15 528638629
15 528638629
15 528638629
15 528638629
However, if I use srand before a for loop as follows-
srand(time(NULL));
for (int i = 0; i<10; i++)
{
printf("%d\n", rand()%1000000);
}
The output changes as follows-
638629
290058
512341
826358
80629
Why is this difference in behaviour? If I keep srand() inside the for loop in the last example, it again starts printing same values again and again. I apologise in advance if this is a stupid question.
Also, I'm using GCC on Ubuntu, if it makes a difference.

Here's the implementation of srand() and rand() in MSVC.
unsigned long rand_key;
void srand(unsigned long seed) {
rand_key = seed;
}
int rand(void) {
return ((rand_key = (rand_key * 214013L + 2531011L)) >> 16) & 0x7FFF;
}
Implementations on other platforms may differ, but they're essentially the same (calculating the next number from the current number). So calling srand() with the same seed is guaranteed to generate the exactly same sequence.
You can mix some stuff up to get a better seed:
#include <time.h>
#include <unistd.h>
srand( (unsigned)time(NULL) ^ getpid() );

Related

rand() Function Does not Work as Expected in C [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
using rand to generate a random numbers
(6 answers)
Closed 1 year ago.
I'm using the rand function in my program in a for loop but it generates the same number all time.
for(a=0, a<10; a++){
srand(3);
int sleep = (rand() % 400) + 500;
}
It always generates 683 or something like that. What's the reason? How can I fix that?
Use the call of the function srand before the loop like for example
#include <stdlib.h>
#include <time.h>
//...
srand( ( unsigned int )time( NULL ) );
for(a=0, a<10; a++){
int sleep = (rand() % 400) + 500;
//...
}
Otherwise you will get the same values according to the call srand( 3 ); because "if srand is then called with the
same seed value, the sequence of pseudo-random numbers shall be repeated." (the C Standard, 7.22.2.2 The srand function).
You are calling srand from inside of your loop. Each time you call it, you are setting the seed that is used to generate random numbers.
Move it outside of your loop as such:
srand(3);
for(a=0, a<10; a++){
int sleep = (rand() % 400) + 500;
}
Additionally, each time you run your program, it will generate the same sequence of numbers. If you wish to avoid that, you'll need to pick a different seed for each run. Typically this is a number that changes each time, such as time of day in seconds or something more unique.
srand((unsigned int)time(NULL));

Why does my srand(time(NULL)) function generate the same number every time in c? [duplicate]

This question already has answers here:
Random numbers in C
(10 answers)
How can I generate different random numbers for each player?
(3 answers)
Closed 4 years ago.
So I was creating a program that would call a function and return 0 or 1 (0 meaning tails and 1 meaning heads) and then use that to print the outcome of 100 flips.
It seemed simple enough thinking I could use srand(time(NULL)) to seed rand() with constantly varying seeds. Here was my first crack.
#include <stdio.h>
#include <stdlib.h>
int flip();
int main(void) {
int heads = 0;
int tails = 0;
for (short int count = 1; count <= 100; ++count) {
int number = flip();
if (number == 0) {
printf("%s", "Tails");
++tails;
}
else if (number == 1) {
printf_s("%s", "Heads");
++heads;
}
}//end for
printf_s("\n%d Tails\n", tails);
printf_s("%d Heads", heads);
}//end main
int flip(void) {
srand(time(NULL));
int number = (int)rand();
printf("%d", number%2);
return number%2;
}//end flip
I would run the program and my rand() value would always be a five digit integer repeated in each iteration of the for statement (i.e 15367, 15745, or 15943).
I messed around until I discovered changing srand(time(NULL)) to srand(time(NULL)*time(NULL)/rand()) did the trick.
My only thought is that the time between each for iteration is so small the the time(NULL) part of the srand() function doesn't change enough to feed a different seed value.
I also tried srand(time(NULL)/rand()), however, this produced the same result (52 heads 48 tails) every time I ran the program (20+times); however, the rand() values were all different from each other.
I do not know why these things happened, or why the final srand(time(NULL)*time(NULL)/rand()) function worked, and I would love it if someone could explain!
The reason is, that time(NULL) changes only once per second!
This means, that you seed the random number generator 100 times with the same seed.
A better way is to seed the RNG only once at start of the process (at the head of main(), then you should get different values.
If you start your program more often than once a second, you could also seed it with
srand(time(NULL)+getpid());
or similar.

Why below code wont generate a random string on multiple runs? [duplicate]

This question already has answers here:
Why do I always get the same sequence of random numbers with rand()?
(12 answers)
If I don't specify srand(), what seed does rand() use?
(5 answers)
Closed 5 years ago.
Program uses rand() function to generate random index. But it always produces same string no matter what! Why won't this work?
void rand_string()
{
int a[10];
int i;
char b[] = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM";
printf("%d", sizeof(b) / sizeof(b[0]));
for(i = 0; i < 10; i++)
{
int gen_rand = rand() % 63;
a[i] = b[gen_rand];
}
for(i = 0; i < 10; i++)
printf("%c", a[i]);
}
Use srand function to seed the random generator
srand((unsigned)time(NULL));
Note that you only have to seed once in your program otherwise it will not work properly.
You could firstly define a random function specific to your needs, i.e. generating in specific range (the length of the current string), like so:
int random(int min, int max)
{
return min + (rand()) / (RAND_MAX / (max - min));
}
then in your string-random-generator function you could also add a random length to every string:
void rand_str()
{
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; // define only on first call
// call srand() using #include <time.h> ; could be outside of function, i.e. in main()
int length = random(0, 10); // get random length in [0, 10] on each call
// use length and random(0, sizeof(alphanum) / sizeof(alphanum[0])) in for loop
// everything else is the same...
}
use the keyword static to indicate single1 definition of the array alphanum (think of it that it is like making it global) and call function srand() once, before the use of random().
Note: you should consider modifying your function to a single purpose, i.e. only generating a random string and returning (a pointer to) a string; and printing it in a separate function.
1. Only on the first call of rand_str().

How can i put different number in 2 array on C [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 5 years ago.
I tried to put different random number element in each array.
However that 2 arrays got exactly same 10 random number.
What's wrong with me and how can I solve this?
#define MAX 100
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void number(int* array)
{
srand((long)time(NULL));
for (int i = 0; i < 20; i++)
array[i] = rand() % MAX + 1;
}
void printing(int* p_array)
{
for (int i = 0; i < 20; i++)
printf(" %d", p_array[i]);
puts("");
}
int main(void)
{
int score1[20];
int score2[20];
number(score1);
printing(score1);
number(score2);
printing(score2);
return 0;
}
srand((long)time(NULL));
When you are doing this, you are initializing srand with a seed based on the time the line has been called. The main point of a pseudo-number generator such as srand is that, whenever the seed is the same, the generator will always return the exact same serie of values, so a program using the generator with a specific seed can reproduce the exact same results several times.
The problem is that you initialize srand two times, and that the line is run two times at the exact same time (at least at the same second on such a short program), so the seed is the same. Your two arrays are, thus, strictly identical.
Call this line only once at the beginning of your main function, and you will use only one serie of numbers instead of two identical ones, leading to your two arrays having different values.
int main(void)
{
srand(time(NULL));
int score1[20];
int score2[20];
number(score1);
printing(score1);
number(score2);
printing(score2);
return 0;
}
Remove this statement from the number function
srand( (unsigned int)time(NULL));
and place it in main before the calls to number.
Otherwise the expression time(NULL) could yield the same value.
As 4386427 says, the problem is your call to srand(null). It resets the random number generator. If it didn't generate the same number series, then your number generator is broken. Remove it or call it with say the current time will fix the problem.

generate random number in c [duplicate]

While searching for Tutorials on generating random numbers in C I found this topic
When I try to use the rand() function without parameters, I always get 0. When I try to use the rand() function with parameters, I always get the value 41. And whenever I try to use arc4random() and random() functions, I get a LNK2019 error.
Here's what I've done:
#include <stdlib.h>
int main()
{
int x;
x = rand(6);
printf("%d", x);
}
This code always generates 41. Where am I going wrong? I'm running Windows XP SP3 and using VS2010 Command Prompt as compiler.
You should call srand() before calling rand to initialize the random number generator.
Either call it with a specific seed, and you will always get the same pseudo-random sequence
#include <stdlib.h>
int main ()
{
srand ( 123 );
int random_number = rand();
return 0;
}
or call it with a changing sources, ie the time function
#include <stdlib.h>
#include <time.h>
int main ()
{
srand ( time(NULL) );
int random_number = rand();
return 0;
}
In response to Moon's Comment
rand() generates a random number with an equal probability between 0 and RAND_MAX (a macro pre-defined in stdlib.h)
You can then map this value to a smaller range, e.g.
int random_value = rand(); //between 0 and RAND_MAX
//you can mod the result
int N = 33;
int rand_capped = random_value % N; //between 0 and 32
int S = 50;
int rand_range = rand_capped + S; //between 50 and 82
//you can convert it to a float
float unit_random = random_value / (float) RAND_MAX; //between 0 and 1 (floating point)
This might be sufficient for most uses, but its worth pointing out that in the first case using the mod operator introduces a slight bias if N does not divide evenly into RAND_MAX+1.
Random number generators are interesting and complex, it is widely said that the rand() generator in the C standard library is not a great quality random number generator, read (http://en.wikipedia.org/wiki/Random_number_generation for a definition of quality).
http://en.wikipedia.org/wiki/Mersenne_twister (source http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html ) is a popular high quality random number generator.
Also, I am not aware of arc4rand() or random() so I cannot comment.
You need to seed your PRNG so it starts with a different value each time.
A simple but low quality seed is to use the current time:
srand(time(0));
This will get you started but is considered low quality (i.e. for example, don't use that if you are trying to generate RSA keys).
Background. Pseudo-random number generators do not create true random number sequences but just simulate them. Given a starting point number, a PRNG will always return the same sequence of numbers. By default, they start with the same internal state so will return the same sequence.
To not get the same sequence, you change the internal state. The act of changing the internal state is called "seeding".
#include <stdlib.h>
int main()
{
int x;
x = rand(6);
printf("%d", x);
}
Especially as a beginner, you should ask your compiler to print every warning about bad code that it can generate. Modern compilers know lots of different warnings which help you to program better. For example, when you compile this program with the GNU C Compiler:
$ gcc -W -Wall rand.c
rand.c: In function `main':
rand.c:5: error: too many arguments to function `rand'
rand.c:6: warning: implicit declaration of function `printf'
You get two warnings here. The first one says that the rand function only takes zero arguments, not one as you tried. To get a random number between 0 and n, you can use the expression rand() % n, which is not perfect but ok for small n. The resulting random numbers are normally not evenly distributed; smaller values are returned more often.
The second warning tells you that you are calling a function that the compiler doesn't know at that point. You have to tell the compiler by saying #include <stdio.h>. Which include files are needed for which functions is not always simple, but asking the Open Group specification for portable operating systems works in many cases: http://www.google.com/search?q=opengroup+rand.
These two warnings tell you much about the history of the C programming language. 40 years back, the definition of a function didn't include the number of parameters or the types of the parameters. It was also ok to call an unknown function, which in most cases worked. If you want to write code today, you should not rely on these old features but instead enable your compiler's warnings, understand the warnings and then fix them properly.
Also, linear congruential PRNGs tend to produce more randomness on the higher bits that on the lower bits, so to cap the result don't use modulo, but instead use something like:
j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));
(This one is from "Numerical Recipes in C", ch.7)
You first need to seed the generator because it doesn't generate real random numbers!
Try this:
#include <stdlib.h>
#include <time.h>
int main()
{
// random seed, time!
srand( time(NULL) ); // hackish but gets the job done.
int x;
x = rand(); // everytime it is different because the seed is different.
printf("%d", x);
}
Or, to get a pseudo-random int in the range 0 to 19,
for example, you could use the higher bits like this:
j = ((rand() >> 15) % 20;
int *generate_randomnumbers(int start, int end){
int *res = malloc(sizeof(int)*(end-start));
srand(time(NULL));
for (int i= 0; i < (end -start)+1; i++){
int r = rand()%end + start;
int dup = 0;
for (int j = 0; j < (end -start)+1; j++){
if (res[j] == r){
i--;
dup = 1;
break;
}
}
if (!dup)
res[i] = r;
}
return res;
}

Resources