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

时间:2009-05-03 20:53:01

标签: c++ time random standard-library seed

每当我在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;
}

我收到有关第5行从time_t到int的转换的警告:

srand(time(0));

有没有办法摆脱这种警告?

6 个答案:

答案 0 :(得分:8)

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

srand((unsigned) time(0));

答案 1 :(得分:6)

另请注意,此代码:

rand()%6

通常被认为是一种不良做法。 rand()的低位比高位低得多。如果你这样做,你将获得更好的随机性:

(rand() >> 8)%6
例如

编辑:

有关详细信息,请参阅this note以及Dr. Dobbs期刊中的这篇文章,其中至少暗示了原因:

  

注意:请勿使用

  y = rand()  %  M;
     

因为这集中在低位   RAND()。对于线性同余随机   数字生成器,经常rand()   是,较低的字节要少得多   随机比较高的字节。事实上   最低位循环在0和1之间。   因此rand()可以在even和之间循环   奇怪的(尝试一下)。注意rand()没有   必须是线性同余   随机数发生器。它的   完全允许它   更好的东西没有   这个问题。

DDJ:

  

最重要的一点是   来自的输出的低位   通常(线性同余)随机   数字生成器是最少的   “随机。”也就是说,模式   低位是常见的。因此,   您的常规滚动输出   讨论并不奇怪。它,它   依靠鞋面是可以避免的   用于确定整数的位   返回。

例如,如果您想选择随机的“true”或“false”值,并使用了代码:

rand() % 2

然后你可能会看到结果模式:

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

这显然不是随机的,但它是可能正在使用的线性同余生成器的属性。一个更好的方案(对于C ++)可能是使用Boost.Random库,它支持所有类型的可插入随机生成器(包括没有这个缺陷的Mersenne Twister)。

答案 2 :(得分:2)

使用显式强制转换来消除警告:

srand((int)time(0));

答案 3 :(得分:2)

两个旁注:

  • 在C ++中包含C头的标准方法是这样的:#include <cstdio>
  • 传递给time()的参数是一个指针,许多人认为NULL是一个比0更易读的空指针。

答案 4 :(得分:2)

要消除警告,您应该使用静态强制转换为无符号整数。

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

在相关的说明中,rand的结果应该向右移动以消除低位中的任何偏差。

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

最后,在C ++中,C时间和标准库应该包括在:

#include <ctime>
#include <cstdlib>

这会将函数放在适当的命名空间“std”。

答案 5 :(得分:1)

此外,

 rand() % 6

会引入一个小偏见。由于RAND_MAX%6为1,因此0和1将比2到6略微增加。在这种情况下,它们返回5462次,每5461次返回更高的数字,所以你可能不会注意到它。但是,如果您想要的数字范围很大,则偏差可能很大。例如,如果您执行了rand() % 32000,那么0到767范围内的数字会比那些768 - 32000的频率高出两倍。