每当我在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));
有没有办法摆脱这种警告?
答案 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)
两个旁注:
#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的频率高出两倍。