播种随机数生成器C ++

时间:2012-08-13 23:06:36

标签: c++ random

我有两个问题。

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

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

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

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

    EDIT2: 源代码:

    #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 个答案:

答案 0 :(得分:7)

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

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

什么时候应该

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

答案 1 :(得分: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);

答案 2 :(得分:3)

你应该在程序开始时看到一次随机:

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.

}

答案 3 :(得分: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");

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