7

我有两个问题。

  1. 还有哪些其他方法可以在不使用 C++ 的情况下播种伪随机数生成器srand(time(NULL))

  2. 我问第一个问题的原因。我目前使用时间作为生成器的种子,但生成器返回的数字始终相同。我很确定原因是因为存储时间的变量在某种程度上被截断了。(我有一条警告消息说,“隐式转换失去整数精度:'time_t'(又名'long')到'unsigned int')我猜这告诉我,从本质上讲,我的种子直到明年才会改变发生。就我的目的而言,使用时间作为我的种子就可以了,但我不知道如何摆脱这个警告。

我以前从未收到过该错误消息,所以我认为它与我的 Mac 有关。它是 64 位 OS X v10.8。我也在使用 Xcode 编写和编译,但我在其他使用 Xcode 的计算机上没有问题。

编辑:在玩弄和研究更多之后,我发现了 64 位 Mac 存在的一个错误。(如果我弄错了,请纠正我。)如果您尝试让您的 mac 选择 1 到 7 之间的随机数time(NULL)作为种子,您将始终得到数字 4。总是。我最终mach_absolute_time()用来播种我的随机发生器。显然,这消除了我程序的所有可移植性......但我只是一个业余爱好者。

编辑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;
}

我再次运行此代码进行测试。现在它只返回 3。这一定与我的计算机有关,而不是 C++ 本身。

4

4 回答 4

11

Tl; 博士但是,很可能,你做错了。你应该只设置一次种子,而你可能有类似的东西:

for ( ... )
{
   srand(time(NULL));
   whatever = rand();
}

什么时候应该

srand(time(NULL));
for ( ... )
{
   whatever = rand();
}
于 2012-08-13T23:08:07.047 回答
7

1.不是真的。例如,您可以要求用户输入随机种子。或者使用其他一些系统参数,但这不会有什么不同。

2.要消除此警告,您必须进行显式转换。像:

unsigned int time_ui = unsigned int( time(NULL) );
srand( time_ui );

或者

unsigned int time_ui = static_cast<unsigned int>( time(NULL) );

或者

unsigned int time_ui = static_cast<unsigned int>( time(NULL)%1000 );

要检查这是否真的是转换问题,您可以简单地在屏幕上输出您的时间并查看自己

std::cout << time(NULL);
于 2012-08-14T00:18:52.293 回答
5

您应该在程序开始时看到 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.

}
于 2012-08-14T00:05:07.703 回答
0

对于 x86,可以使用直接调用 CPU 时间戳计数器rdtsc,而不是库函数 TIME(NULL)。下面 1) 读取时间戳 2) 汇编中的种子 RAND:

rdtsc
mov edi, eax
call    srand

对于 C++,以下将使用 g++ 编译器完成工作。

asm("rdtsc\n"
    "mov edi, eax\n"
    "call   srand");

注意:但如果代码在虚拟机中运行,则可能不推荐使用。

于 2016-04-13T20:55:32.243 回答