Question

Whenever I use the rand function in C++:

#include<iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;
int main(){
srand(time(0));
int n=(rand()%6)+1;
cout<<"The dice roll is "<<n<<"."<<endl;
}

I get a warning about conversion from time_t to int at line 5:

srand(time(0));

Is there any way to get rid of this warning?

Was it helpful?

Solution

Actually, you should be using an an unsigned int with srand():

srand((unsigned) time(0));

OTHER TIPS

On A different note, this code:

rand()%6

is generally regarded as a bad practice. the lower bits of rand() are significantly less random than the higher bits. You'll get better randomness if you do:

(rand() >> 8)%6

for instance.

EDIT:

For more detail on this, see this note and also this article from Dr. Dobbs journal which at least hint at the reason:

Note: Do NOT use

  y = rand()  %  M;

as this focuses on the lower bits of rand(). For linear congruential random number generators, which rand() often is, the lower bytes are much less random than the higher bytes. In fact the lowest bit cycles between 0 and 1. Thus rand() may cycle between even and odd (try it out). Note rand() does not have to be a linear congruential random number generator. It's perfectly permissible for it to be something better which does not have this problem.

DDJ:

The most important point is that the lower bits of the output from the usual (linear congruential) random number generators are the least "random." That is, patterns in the lower bits are common. Hence, the output from the routine roll in your discussion is not surprising. Also, it is avoidable by relying on the upper bits to determine the integer returned.

For example, if you wanted to choose a random "true" or "false" value, and you used the code:

rand() % 2

Then you might end up seeing the pattern of results:

1,0,1,0,1,0,1,0,1,0 (etc)

This is obviously not that random, but it is a property of the linear congruential generator that might be in use. A better scheme altogether (for C++) might be to use the Boost.Random library which has support for all kinds of pluggable random generators (including Mersenne Twister which does not have this flaw).

Use an explicit cast to get rid of the warning:

srand((int)time(0));

Two side notes:

  • The standard way of including C headers in C++ is like this: #include <cstdio>.
  • The parameter passed to time() is a pointer, and many people think that NULL is a more readable null pointer than 0.

To get rid of the warning you should use a static cast to an unsigned integer.

srand(static_cast<unsigned int>(time(0)));

On a related note, the results of rand should be shifted to the right to remove any bias in the lower bits.

int n = ((rand() >> 8) % 6) + 1;

Finally, in C++ the C time and standard libraries should be included as:

#include <ctime>
#include <cstdlib>

This will place the functions in the appropriate namespace, 'std'.

Also,

 rand() % 6

will introduce a small bias. Since RAND_MAX % 6 is 1, zero and one will turn up slightly more often than two through six. In this case, they be returned 5462 times for every 5461 times the higher numbers are returned, so you probably won't notice it. However, if the range of numbers you want is large, the bias can be significant. For example, if you did rand() % 32000, then number in the range 0 - 767 would turn up twice as often as those 768 - 32000.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top