简体   繁体   English

如何使用rand()摆脱警告? (C ++)

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

Whenever I use the rand function in C++: 每当我在C ++中使用rand函数时:

#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: 我在第5行收到有关从time_t到int转换的警告:

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. rand()的低位比高位的随机性小得多。 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: 有关此问题的更多详细信息,请参阅本说明以及Dobbs博士的这篇文章,其中至少暗示了原因:

Note: Do NOT use 注意:请勿使用

  y = rand() % M; 

as this focuses on the lower bits of rand(). 因为这着重于rand()的低位。 For linear congruential random number generators, which rand() often is, the lower bytes are much less random than the higher bytes. 对于rand()通常是线性同余随机数生成器,较低字节的随机性要比较高字节的随机性小得多。 In fact the lowest bit cycles between 0 and 1. Thus rand() may cycle between even and odd (try it out). 实际上,最低位在0和1之间循环。因此rand()可以在偶数和奇数之间循环(尝试一下)。 Note rand() does not have to be a linear congruential random number generator. 注意rand()不必是线性同余随机数生成器。 It's perfectly permissible for it to be something better which does not have this problem. 完全可以允许它做得更好,没有这个问题。

DDJ: 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: 例如,如果要选择随机的“ true”或“ false”值,则可以使用以下代码:

rand() % 2

Then you might end up seeing the pattern of results: 然后,您可能最终会看到结果的模式:

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

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). 更好的方案(针对C ++)可能是使用Boost.Random库,该库支持所有类型的可插拔随机生成器(包括不具有此缺陷的Mersenne Twister)。

使用显式强制摆脱警告:

srand((int)time(0));

Two side notes: 两个注意事项:

  • The standard way of including C headers in C++ is like this: #include <cstdio> . 在C ++中包括C标头的标准方式是这样的: #include <cstdio>
  • The parameter passed to time() is a pointer, and many people think that NULL is a more readable null pointer than 0 . 传递给time()的参数是一个指针,许多人认为NULL是比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. 与此相关的是,rand的结果应移到右侧以消除低位的任何偏差。

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

Finally, in C++ the C time and standard libraries should be included as: 最后,在C ++中,C时间库和标准库应包括:

#include <ctime>
#include <cstdlib>

This will place the functions in the appropriate namespace, 'std'. 这会将函数放置在适当的名称空间“ 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. 由于RAND_MAX%6为1,所以零和1的出现频率将比2到6稍微高一些。 In this case, they be returned 5462 times for every 5461 times the higher numbers are returned, so you probably won't notice it. 在这种情况下,每返回5461次返回较高的数字,它们就会被返回5462次,因此您可能不会注意到它。 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. 例如,如果您执行rand() % 32000 ,则rand() % 32000范围内的数字出现频率将是768-32000的两倍。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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