How unique is rand() in C? - c

I am using rand() for a 6 digit field which needs unique values. Am I doing it right?
What are the odds, rand() can give me similar values on consecutive or frequent calls?
It was unique when I used rand(). But, returned same number when I called srand(time(NULL)) or srand(clock()). Seems, like it's working opposite for me. Or is it?

As others have pointed out, uniqueness is not guaranteed. However you are probably seeing repeated numbers because you are using srand() and rand() incorrectly.
srand() is used to seed the random number generator. that means a series of calls to rand() after a call to srand will produce a particular series of values. If you call srand() with the same value then rand() will produce the same series of values (for a given implementation, there's no guarantee between different implementations)
int main() {
srand(100);
for(int i = 0; i<5; ++i)
printf("%d\n",rand());
printf("\nreset\n\n");
srand(100);
for(int i = 0; i<5; ++i)
printf("%d\n",rand());
}
for me this produces:
365
1216
5415
16704
24504
reset
365
1216
5415
16704
24504
time() and clock() return the time, but if you call them quickly enough then the value returned will be the same, so you will get the same series of values out of rand().
Additionally rand() is generally not a very good random number generator and using it usually means you have to transform the series of numbers to the distribution you actually need. You should find a different source of randomness and either learn the proper ways to produce the distribution you want or use a library that can do it for you. (for example one common method of producing a 'random' number between 0 and N is to do rand() % N but this is not really the best method.
C++ provides a much better random number library in <random>. It provides different PRNG algorithms, such as linear_congruential, mersennne_twister, and possibly even a cryptographically secure RNG (depending on the implementation). It also provides objects for producing a variety of distributions, such as uniform_int_distribution which should avoid the mistake make in rand() % N.

rand() returns values between 0 and RAND_MAX. Since it's a discrete uniform distribution, you have a probability of 1/(RAND_MAX+1) of repeating a number and therefore, uniqueness is not guaranteed.
srand(seed) initializes your random number generator so that the sequence of numbers obtained from rand() is the same every time given that you initialize it with seed every time.
In your example seed = time(NULL) which is the number of seconds elapsed from January 1, 1970 thus ensuring a different seed, and thus a different sequence of random numbers for every call to srand(time(NULL)) (assuming that it's not made within the same second).

Random numbers are random, not unique. Just like a situation with throwing dice when you can roll several sixes in a row, your rand can (and should) sometimes give you runs of identical numbers.
In order to make sure that the numbers are unique, build a set where you register each of the numbers that you have added already. When a random number comes up more than once, throw the second one away, and go for the next one.

What are the odds, rand() can give me similar values on consecutive or frequent calls?
The algorithm of rand is unspecified in C. So is the quality of the randomness of the numbers returned by rand.

Related

Generate random numbers based on seed value

Can someone explain to me what seed value is? For example I have this code:
int MIN=0;
int MAX=100;
srand((unsigned) time(NULL));
srand(2020);
int num = (int)(rand() / (RAND_MAX + 1.0 + MIN) * MAX);
I am required to use a seed value of 2020 to generate numbers between 0 to 100. I checked everywhere but seems like there is no tutorial that explains what seed value is, and how the code should change from the default seed value. Line 3 of my code assumes the default seed value, so it does not work with a seed value of 2020. Also, MAX is 100, and MIN is 0.
Thanks in advance!
The pseudo-random number generator is initialized using the argument passed as seed. For every different seed value used in a call to srand, the pseudo-random number generator can be expected to generate a different succession of results in the subsequent calls to rand.
http://www.cplusplus.com/reference/cstdlib/srand/
Then calling rand() will return a pseudo-random number in the range of 0 to RAND_MAX.
If you want rand() to produce different random numbers, ensure you are not calling srand(2020) each time you are calling rand(). As you only need to seed the random number generation once.
The seed has 2 usages. The most common one is to start a random generator with a different value. It matters when you want to produce a random value for a crypto algorithm. When you start the program, you do not want to use the same value on each run...
The other usage is to generate a reproducible pseudo-random sequence. It matters when you want reproducible tests, or when you want to exchange with others with random data but want all to use the same sequence. It is very often used in tutorials to have a consistent sequence that the user will be able to reproduce when following the tuto. It is also used by teachers because it is easier to see if students have found the correct result (if every student uses a different sequence, all results would be different)
The rand function generates some sequence of numbers. (The sequence is calculated but is intended to serve as if the numbers were random, so they are called pseudo-random.) By itself, it will always generate the same sequence of numbers in a program. We use srand to choose which sequence of numbers it generates. (Most commonly, rand generates a cycle of the same numbers, if called enough times, and srand merely chooses where in that cycle we start.)
So, you call srand to set the starting point of the sequence for rand. The value you pass to srand is any unsigned int value. In the C standard, there is no specified meaning for the value. You just give srand a number like 1 to get one sequence, 2 to get a different sequence, 3 to get another sequence, and so on. You have no other control over the actual values generated; setting the seed to some particular value does not guarantee the first rand call will return any particular documented value.
The C standard also does not specify any method for calculating the numbers in the sequence. Each C implementation may choose its own method. Some C implementations use bad methods, in which the numbers are not very random-like at all, and some patterns can be easily observed. (For this reason, it is often recommended to use alternatives, like Unix’s srandom and random.)
When a program is being debugged or is being used as a class assignment, it is common to call srand with a fixed value, like srand(2020). This results in rand generating the same numbers each time. That makes it easier to debug the program or to check the results of student programs. When varying sequences of numbers are designed, it is common to call srand with srand(time(NULL)). Assuming the time is available (time(NULL) may return −1 for an error), this causes the program to use different sequences at different times. (Commonly, the value of time as an integer changes once per second, but this can vary depending on the C implementation.)
In C, srand takes a seed that determines the sequence of numbers rand will generate (also known as pseudorandom numbers), as long as the program doesn't change and the program uses the same implementation of rand and srand.
In C, srand and rand can't be used to create a reproducible sequence of pseudorandom numbers, because the standard that defines the C language doesn't specify what that sequence is, even if the seed is given. Notably, rand uses an unspecified pseudorandom number algorithm, and that algorithm can differ between C implementations, including versions of the same standard library. It's not the "compiler", the "system", or the "architecture" that decides which implementation of rand and srand is used. See also these questions:
How predictable is the result of rand() between individual systems?
Does Python have a function to mimic the sequence of C's rand()?
Why is the use of rand() considered bad?
To generate a random number with a specific seed use srand to set the seed for one-time only.
Then use rand to generate the random number. The default range is between 0 and RAND_MAX (RAND_MAX = 32767).
To define the maximum number just override RAND_MAX via precompiler statements (Side effects included) or use Modulo %.
Override RAND_MAX
#ifdef RAND_MAX
#undef RAND_MAX
#define RAND_MAX 100
#endif
Use Modulo
srand(2020);
int random_number = rand() % 100;

Does rand() indeed produce a random value when the random number generator has been seeded?

I know that in order to avoid repeating the same output of the rand() function a pseudo-random number generator must be seeded with the srand function. That means, if I try say srand(1), the output of the rand() will be one value, if I try srand(2), the output will contain another value. But when I try the first argument again like srand(1), the value will be the same as in the first output. This issue made me think that all random values would be predictable in some way. Is it possible to have different output for the same seed (say if I try the same seed tomorrow)? Or are random values predictable indeed?
With the traditional definition of a pseudorandom generator, if you know what the generator has been seeded with, then the sequence of output values is completely determined and not random. This means that if you knew the seed for a random generator, then you could predict every single output that generator would produce from that point forward. (A good random number generator is one where seeing a sequence of outputs of the generator does not let you easily reverse-engineer what the random seed is or predict other values.)
I seem to remember reading a while back that, a while back, some popular poker websites were not doing a good job choosing their random seeds. Some people figured out that you could input the pattern of cards you were seeing, and the system could then reverse-engineer the random seed and let you predict all the future cards. Oops. These days, we have cryptographically secure pseudorandom generators based on encryption routines that, at least when it comes to what's known in the open literature, can't be predicted even if you have gigabytes of random bits of output from the generators.
If you do need to get something that really isn't predictable - that is, you want to get a bunch of truly random bits - you'll need to use something other than a pseudorandom number generator. Most operating systems have some mechanism in place to generate values that do appear to be truly random. They might, for example, look at how long it takes for different capacitors to discharge on the motherboard, or factor in timing information from a clock, or see how the user interacts with the keyboard, etc. These data can be fed into something called an entropy accumulator that slowly builds up more and more random bits. If you need a value that's truly random and can't be predicted in advance, you can check your particular OS for the mechanism used to get data from the entropy accumulator. (You can read from /dev/random on UNIX-style machines, for example.)
Often, pulling data from the entropy accumulator takes time, since the computer has to wait long enough for enough different sources to mix together to give you back high-quality random data. A common strategy, therefore, is to use the entropy accumulator to get a high-quality random seed, then "stretch" the randomness by using it as the seed of a strong pseudorandom generator.
Here is the language of the C Standard:
7.22.2 Pseudo-random sequence generation functions
7.22.2.1 The rand function
Synopsis
#include <stdlib.h>
int rand(void);
The rand function computes a sequence of pseudo-random integers in the range 0 to RAND_MAX
The rand function is not required to avoid data races with other calls to pseudo-random sequence generation functions. The implementation shall behave as if no library function calls the rand function.
Returns
The rand function returns a pseudo-random integer.
Environmental limits
The value of the RAND_MAX macro shall be at least 32767.
7.22.2.2 The srand function
Synopsis
#include <stdlib.h>
void srand(unsigned int seed);
The srand function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to rand. If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated. If rand is called before any calls to srand have been made, the same sequence shall be generated as when srand is first called with a seed value of 1.
The srand function is not required to avoid data races with other calls to pseudo-random sequence generation functions. The implementation shall behave as if no library function calls the srand function.
Returns
The srand function returns no value.
In other words, rand() returns a pseudo-random sequence of integers between 0 and RAND_MAX. The sequence is not random, it is predictable for every value passed to srand(), including if srand() is never called.
In order to try and get different sequences for successive runs of the program, srand() can be called with a rapidly varying value, such as the return value of clock(). Note that calling srand(time(NULL)) will produce the same sequence for multiple runs of the program during the same second.

How to generate either 0 or 1 randomly in C

I have read so many posts on this topic:
How does rand() work? Does it have certain tendencies? Is there something better to use?
How does the random number generator work in C
and this is what I got:
1) xn+1 depends on xn i.e., previous random number that is generated.
2) It is not recommended to initialize the seed more than once in the program.
3) It is a bad practice to use rand()%2 to generate either 0 or 1 randomly.
My questions are:
1) Are there any other libraries that I missed to take a look to generate a completely random number (either 0 or 1) without depending on previous output?
2) If there is any other work around using the inbuilt rand() function to satisfy the requirement?
3) What is the side effect of initializing the seed more than once in a program?
Code snippet:
srand(time(NULL));
d1=rand()%2;
d2=rand()%2;
Here my intention is to make d1 and d2 completely independent of each other.
My initial thought is to do this:
srand(time(NULL));
d1=rand()%2;
srand(time(NULL));
d2=rand()%2;
But as I mentioned earlier which is based on other posts, this is a bad practice I suppose?
So, can anyone please answer the above questions? I apologize if I completely missed an obvious thing.
Are there any other libraries that I missed to take a look to generate a completely random number between 0 and 1 without depending on previous output?
Not in the standard C library. There are lots of other libraries which generate "better" pseudo-random numbers.
If there is any other work around using the inbuilt rand() function to satisfy the requirement?
Most standard library implementations of rand produce sequences of random numbers where the low-order bit(s) have a short sequence and/or are not as independent of each other as one would like. The high-order bits are generally better distributed. So a better way of using the standard library rand function to generate a random single bit (0 or 1) is:
(rand() > RAND_MAX / 2)
or use an interior bit:
(rand() & 0x400U != 0)
Those will produce reasonably uncorrelated sequences with most standard library rand implementations, and impose no more computational overhead than checking the low-order bit. If that's not good enough for you, you'll probably want to research other pseudo-random number generators.
All of these (including rand() % 2) assume that RAND_MAX is odd, which is almost always the case. (If RAND_MAX were even, there would be an odd number of possible values and any way of dividing an odd number of possible values into two camps must be slightly biased.)
What is the side effect of initializing the seed more than once in a program?
You should think of the random number generator as producing "not very random" numbers after being seeded, with the quality improving as you successively generate new random numbers. And remember that if you seed the random number generator using some seed, you will get exactly the same sequence as you will the next time you seed the generator with the same seed. (Since time() returns a number of seconds, two successive calls in quick succession will usually produce exactly the same number, or very occasionally two consecutive numbers. But definitely not two random uncorrelated numbers.)
So the side effect of reseeding is that you get less random numbers, and possibly exactly the same ones as you got the last time you reseeded.
1) Are there any other libraries that I missed to take a look to
generate a completely random number between 0 and 1 without depending
on previous output?
This sub-question is off-topic for Stack Overflow, but I'll point out that POSIX and BSD systems have an alternative random number generator function named random() that you could consider if you are programming for such a platform (e.g. Linux, OS X).
2) If there is any other work around using the inbuilt rand() function
to satisfy the requirement?
Traditional computers (as opposed to quantum computers) are deterministic machines. They cannot do true randomness. Every completely programmatic "random number generator" is in practice a psuedo-random number generator. They generate completely deterministic sequences, but the values from a given set of calls are distributed across the generator's range in a manner approximately consistent with a target probability distribution (ordinarily the uniform distribution).
Some operating systems provide support for generating numbers that depend on something more chaotic and less predictable than a computed sequence. For instance, they may collect information from mouse movements, CPU temperature variations, or other such sources, to produce more objectively random (yet still deterministic) numbers. Linux, for example, has such a driver that is often exposed as the special file /dev/random. The problem with these is that they have a limited store of entropy, and therefore cannot provide numbers at a sustained high rate. If you need only a few random numbers, however, then that might be a suitable source.
3) What is the side effect of initializing the seed more than once in
a program?
Code snippet:
srand(time(NULL));
d1=rand()%2;
d2=rand()%2;
Here my intention is to make d1 and d2 completely independent of each
other.
My initial thought is to do this:
srand(time(NULL));
d1=rand()%2;
srand(time(NULL));
d2=rand()%2;
But as I mentioned earlier which is based on other posts, this is a
bad practice I suppose?
It is indeed bad if you want d1 and d2 to have a 50% probability of being different. time() returns the number of seconds since the epoch, so it is highly likely that it will return the same value when called twice so close together. The sequence of pseudorandom numbers is completely determined by the seed (this is a feature, not a bug), and when you seed the PRNG, you restart the sequence. Even if you used a higher-resolution clock to make the seeds more likely to differ, you don't escape correlation this way; you just change the function generating numbers for you. And the result does not have the same guarantees for output distribution.
Additionally, when you do rand() % 2 you use only one bit of the approximately log2(RAND_MAX) + 1 bits that it produced for you. Over the whole period of the PRNG, you can expect that bit to take each value the same number of times, but over narrow ranges you may sometimes see some correlation.
In the end, your requirement for your two random numbers to be completely independent of one another is probably way overkill. It is generally sufficient for the pseudo-random result of one call to be have no apparent correlation with the results of previous calls. You probably achieve that well enough with your first code snippet, even despite the use of only one bit per call. If you prefer to use more of the bits, though, then with some care you could base the numbers you choose on the parity of the count of how many bits are set in the values returned by rand().
Use this
(double)rand() / (double)RAND_MAX
completely random number ..... without depending on previous output?
Well in reality computers can't generate completely random numbers. There has to be some dependencies. But for almost all practical purposes, you can use rand().
side effect of initializing the seed more than once
No side effect. But that would mean you're completely invalidating the point of using rand(). If you're re initilizeing seed every time, the random number is more dependent on time(and processor).
any other work around using the inbuilt rand() function
You can write something like this:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(int argc,char *argv[])
{
srand(time(NULL));
printf("%lf\n",(double)rand()/(double)RAND_MAX);
printf("%lf\n",(double)rand()/(double)RAND_MAX);
}
If you want to generate either a 0 or a 1, I think using rand()%2 is perfectly fine as the probability of an even number is same as probability of an odd number(probability of all numbers is equal for an unbiased random number generator).

Random Number In C Independent Of Time

Is there a way to generate random numbers in c language independent of time.
The idea is that I want to generate an array of random numbers at a time,but since rand() method depends on time,all the values in the array are generated similarly.
rand() doesn't depend on time. People typically seed their pseudo-random number generator using the current time (through the srand() function), but they don't have to. You can just pass whatever number you want to srand().
If your random numbers aren't of a high enough quality for your purposes (libc's rand is notorious for its inadequacy), you should look at other sources of randomness. On most operating systems, you can get high-quality random data just by reading from /dev/random (or /dev/urandom), and the Windows API provides CryptGenRandom. There are also a lot of cross-platform libraries that provide high-quality PRNGS; OpenSSL is one of them.
rand() generates values sequentially (in a time-sequence), but does not depend upon time (as in "time of day"), unless you seed the generator with srand(time(NULL)). If you don't do this, it's dependent on 1 (one).
There's also rand_r() (POSIX) to return the value of the current seed. You could use these to coordinate multiple streams of random-numbers, by saving and restoring the appropriate seed values.
For a non-deterministic seed without using time(NULL) you'll probably have to resort to a system-specific source (/dev/random on unix).
At all costs don't do this, and proceed to use myrand() as a replacement for rand(). This will return the same value for each call during each clock second.
unsigned myrand() { // BAD! NO!
srand(time(NULL)); // re-seeding destroys the properties of `rand()`
return rand();
}
If you call srand(), it should be just once at the beginning of the program.
The sequential determinism of rand() is actually a very useful property for testing programs. What you get is an (almost-)random, but repeatable sequence. If you print out the seed value at the start of the program, you can re-use the same value to produce the same results (like if it doesn't work on that run).

How does the random number generator work in C?

I'm trying to generate random number between 0 and 40(inclusive).
So the code I Implemented is this-
y=rand()%41;
However everytime I click compile and hit Run. It outputs the same random numbers.
As in say for instance I ran this in a loop.
for(i=0;i<4;i++)
{
y=rand()%41;
printf("%d ",y);
}
Every single time, the output is the same 4 numbers. It always outputs 14,2,etc etc on the terminal. No matter what.
So my first question is, why is this happening?
and Secondly, how does the random number generator work in C?
I thought since I include time.h library, the numbers are generated through some standard algorithm using the system time. And since the system time is continuously changing, the numbers that are generated should also change every time I run the program.
rand() generates only pseudorandom numbers. This means that every time you run your code you will get exactly the same sequence of numbers.
Consider using
srand(time(NULL))
to get every time different numbers. In fact a possible implementation for rand is
next = next * 1103515245 + 12345;
return (UINT32)(next>>16) & RAND_MAX;
where next is defined as
static UINT32 next = 1;
Calling srand() has the effect of changing the initial value of next, thus changing the "next" value you get as result.
As for how it works, it depends. Many implementations use a Linear Congruential Generator, with different parameters.
The algorithm used for rand is unspecified by the C Standard,
By specification, if you don't call srand before a call to rand in your program, it is as if srand(1) was called: the seed value will be 1 at every execution of the program and the generated sequence will be always the same.
A common way to have different seeds for different executions of the program is to use a seed which depends on the current time like:
srand(time(NULL));
This is actually a FAQ on comp.lang.c. Here's the solution that they suggest:
(int)((double)rand() / ((double) RAND_MAX + 1) * N )
Where N is the ceiling of your range of random numbers. This is because the low order bits on bad C compilers are "shockingly non-random". This doesn't get around the need for using srand(). Note, however that srand( time(NULL) ) should be called outside of your loop... time() has a resolution of 1 second, so calling it inside of the loop will re-initialize your random number generator to the same seed many times in a row.
The need for this is probably largely historical, I'm sure that modern compilers probably don't have random number generators which emit really bad random numbers, but I remember writing a program using the Borland C compiler which would cycle through about 5 numbers when I used rand() % 41 repeatedly.
Reason is that rand() is using the same seeding everytime you run. You have to seed it yourself. srand ( time(NULL) );` is usually used to initialize random seed.
It is generated by an argument passed seed. To generate different numbers add this before calling the rand() function:
srand (time(NULL));
This generates a new random seed.
You should have this library: #include <time.h> And if you still have an error use this one as well: #include <stdlib.h>

Resources