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?
有没有办法摆脱这个警告?
6 个解决方案
#1
Actually, you should be using an an unsigned int with srand():
实际上,你应该使用带有srand()的unsigned int:
srand((unsigned) time(0));
#2
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()的低位比高位低得多。如果您这样做,您将获得更好的随机性:
(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(). 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.
因为这集中在rand()的低位。对于rand()经常使用的线性同余随机数生成器,较低的字节比较高的字节的随机性要小得多。事实上,最低位循环在0和1之间。因此rand()可以在偶数和奇数之间循环(尝试出来)。注意rand()不必是线性同余随机数生成器。它是完全允许的更好的东西没有这个问题。
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)
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,它没有这个缺陷)。
#3
Use an explicit cast to get rid of the warning:
使用显式强制转换来消除警告:
srand((int)time(0));
#4
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 thatNULL
is a more readable null pointer than0
.
在C ++中包含C头的标准方法是这样的:#include
传递给time()的参数是一个指针,很多人认为NULL是一个比0更可读的空指针。
#5
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'中。
#6
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.
会引入一个小偏见。由于RAND_MAX%6为1,因此0和1将比2到6略微增加。在这种情况下,它们返回5462次,每5461次返回更高的数字,所以你可能不会注意到它。但是,如果您想要的数字范围很大,则偏差可能很大。例如,如果你执行了rand()%32000,那么0到767范围内的数字将是那些768 - 32000的两倍。
#1
Actually, you should be using an an unsigned int with srand():
实际上,你应该使用带有srand()的unsigned int:
srand((unsigned) time(0));
#2
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()的低位比高位低得多。如果您这样做,您将获得更好的随机性:
(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(). 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.
因为这集中在rand()的低位。对于rand()经常使用的线性同余随机数生成器,较低的字节比较高的字节的随机性要小得多。事实上,最低位循环在0和1之间。因此rand()可以在偶数和奇数之间循环(尝试出来)。注意rand()不必是线性同余随机数生成器。它是完全允许的更好的东西没有这个问题。
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)
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,它没有这个缺陷)。
#3
Use an explicit cast to get rid of the warning:
使用显式强制转换来消除警告:
srand((int)time(0));
#4
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 thatNULL
is a more readable null pointer than0
.
在C ++中包含C头的标准方法是这样的:#include
传递给time()的参数是一个指针,很多人认为NULL是一个比0更可读的空指针。
#5
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'中。
#6
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.
会引入一个小偏见。由于RAND_MAX%6为1,因此0和1将比2到6略微增加。在这种情况下,它们返回5462次,每5461次返回更高的数字,所以你可能不会注意到它。但是,如果您想要的数字范围很大,则偏差可能很大。例如,如果你执行了rand()%32000,那么0到767范围内的数字将是那些768 - 32000的两倍。