播种随机数生成器 C++
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11943525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Seeding a random number generator C++
提问by Martin York
I have two questions.
我有两个问题。
What other ways are there to seed a psuedo-random number generator in C++ without using
srand(time(NULL))
?The reason I asked the first question. I'm currently using time as my seed for my generator, but the number that the generator returns is always the same. I'm pretty sure the reason is because the variable that stores time is being truncated to some degree. (I have a warning message saying, "Implicit conversion loses integer precision: 'time_t' (aka 'long') to 'unsigned int') I'm guessing that this is telling me that in essence my seed will not change until next year occurs. For my purposes, using time as my seed would work just fine, but I don't know how to get rid of this warning.
还有什么其他方法可以在不使用的情况下在 C++ 中播种伪随机数生成器
srand(time(NULL))
?我问第一个问题的原因。我目前使用时间作为生成器的种子,但生成器返回的数字始终相同。我很确定原因是因为存储时间的变量在某种程度上被截断了。(我有一条警告消息说,“隐式转换失去整数精度:'time_t'(又名'long')到'unsigned int')我猜这告诉我本质上我的种子直到明年才会改变发生。为了我的目的,使用时间作为我的种子会很好,但我不知道如何摆脱这个警告。
I have never gotten that error message before, so I assume it has something to do with my Mac. It's 64-bit OS X v10.8. I'm also using Xcode to write and compile, but I had no problems on other computers with Xcode.
我以前从未收到过该错误消息,因此我认为它与我的 Mac 有关。它是 64 位 OS X v10.8。我也在使用 Xcode 编写和编译,但我在其他计算机上使用 Xcode 没有问题。
Edit:
After toying and researching this more, I discovered a bug that 64-bit Macs have. (Please correct me if I am mistaken.) If you try to have your mac select a random number between 1 and 7 using time(NULL)
as the seed, you will always get the number four. Always. I ended up using mach_absolute_time()
to seed my randomizer. Obviously this eliminates all portability from my program... but I'm just a hobbyist.
编辑:在玩弄和研究更多之后,我发现了一个 64 位 Mac 有的错误。(如果我弄错了,请纠正我。)如果您尝试让您的 mac 选择一个 1 到 7 之间的随机数time(NULL)
作为种子,您将始终得到数字 4。总是。我最终使用mach_absolute_time()
种子我的随机数。显然,这消除了我的程序的所有可移植性……但我只是一个业余爱好者。
Edit2: Source code:
编辑2:源代码:
#include <iostream>
#include <time.h>
using namespace std;
int main(int argc, const char * argv[]) {
srand(time(NULL));
cout << rand() % 7 + 1;
return 0;
}
I ran this code again to test it. Now it's only returning 3. This must be something to do with my computer and not the C++ itself.
我再次运行这段代码来测试它。现在它只返回 3。这一定与我的计算机有关,而不是 C++ 本身。
回答by Luchian Grigore
Tl;dr but, most likely, you're doing it wrong. You're only supposed to set the seed once, whereas you might have something like:
Tl;dr 但是,很可能,你做错了。您只应该设置一次种子,而您可能有以下内容:
for ( ... )
{
srand(time(NULL));
whatever = rand();
}
when it should be
什么时候应该
srand(time(NULL));
for ( ... )
{
whatever = rand();
}
回答by klm123
1.Not really. You can ask user to input random seed, for example. Or use some other system parameters, but this won't make a difference.
1.不是真的。例如,您可以要求用户输入随机种子。或者使用一些其他系统参数,但这不会有什么区别。
2.To rid of this warning you have to do explicit conversion. Like:
2.要消除此警告,您必须进行显式转换。喜欢:
unsigned int time_ui = unsigned int( time(NULL) );
srand( time_ui );
or
或者
unsigned int time_ui = static_cast<unsigned int>( time(NULL) );
or
或者
unsigned int time_ui = static_cast<unsigned int>( time(NULL)%1000 );
to check whether this is really conversion problem you can simply output your time on the screen and see yourself
要检查这是否真的是转换问题,您可以简单地在屏幕上输出您的时间并查看您自己
std::cout << time(NULL);
回答by Martin York
You should see random once at the begining of you program:
您应该在程序开始时看到 random 一次:
int main()
{
// When testing you probably want your code to be deterministic
// Thus don't see random and you will get the same set of results each time
// This will allow you to use unit tests on code that use rand().
#if !defined(TESTING)
srand(time(NULL)); // Never call again
#endif
// Your code here.
}
回答by codechimp
For x86, direct call to the CPU time stamp counter rdtsc
, instead of a library function TIME(NULL), could be used. Below 1) reads timestamp 2) seed RAND in assembly:
对于 x86,可以直接调用 CPU 时间戳计数器rdtsc
,而不是库函数 TIME(NULL)。下面 1) 在汇编中读取时间戳 2) 种子 RAND:
rdtsc
mov edi, eax
call srand
For C++, the following would do the job with g++ compiler.
对于 C++,以下将使用 g++ 编译器完成这项工作。
asm("rdtsc\n"
"mov edi, eax\n"
"call srand");
NOTE: But may not be recommended if code is running in virtual machine.
注意:但如果代码在虚拟机中运行,则可能不推荐。