简体   繁体   中英

How can I get rid of the warning with rand()? (C++)

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?

实际上,您应该使用带有srand()unsigned int

srand((unsigned) time(0));

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).

使用显式强制摆脱警告:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM