经过一段时间浏览问题和谷歌搜索,我发现自己痛苦,没有任何"随机"发生器真的是随机的,我的意思是随机的?总随机性,我在编译后发现的所有算法,并且多次运行打印大量的值,结果是相同的,或者至少找到一个模式.这是非常糟糕的,我正在为MMO服务器做一个随机数生成器,其功能将来自升级项目,将一组玩家分成团队,模式总是,总是坏的,想象每次我重新启动程序生成相同的数字顺序.我的想法是得到随机数的最好方法是弄乱时间,你永远不知道什么是确切的时间会发生什么,如果时间非常精确甚至更好.我想出了一个很棒的解决方案.
inline __int64 NanoTime()
{
struct { int low, high; } Nano;
__asm push EAX
__asm push EDX
__asm __emit 0fh __asm __emit 031h
__asm mov Nano.low, EAX
__asm mov Nano.high, EDX
__asm pop EDX
__asm pop EAX
return *(__int64 *)( &Nano );
}
static DWORD g_Prev = NanoTime();
__int64 xRandom( void )
{
__int64 Now = NanoTime() - g_Prev / 2;
CString strRand, strLast;
strRand.Format( "%I64d", Now );
strLast = strRand.GetAt( strRand.GetLength()-1 );
strLast += strRand.GetAt( strRand.GetLength()-2 );
return( atoi( strLast ) );
}
Run Code Online (Sandbox Code Playgroud)
虽然文本很大,但问题很简单我需要朝着实数最小的算法生成一个方向,我的解决方案每秒被称为数十万次并不是我想要的,它只是在这里给出我需要的方向的暗示.
我已经研究过boost,比如没有使用最低位的订单time(0)等等.但都有一个模式.
在编译它们并运行多次打印大量值后我发现的所有算法结果都相同或者至少找到了一种模式.
坦率地说,这听起来像你尝试过的算法非常差,或者你使用或评估它们的方式有些不完美.
如果标准rand()不够(这是一个很大的if!),你最好的选择是更高级别的伪随机生成器,例如Mersenne Twister.已经证明这种算法通过各种统计随机性测试.
如果你可以选择你使用的硬件,最近的(Ivy Bridge)英特尔硬件提供了一个带有内置熵源的片上随机数发生器:RDRAND.这提供了良好的随机性和高吞吐量,但可能对您的需求有些过分.
想象每次我重新启动程序时都会生成相同的数字顺序
如果这是一个问题,听起来你没有正确播种你的发电机.如果每次运行一次,并使用当前时间作为种子,您将在不同的运行中获得不同的随机序列.
我想出了一个很棒的解决方案.
如果我正确地阅读您的代码,您的熵源是TSC模数100.尝试在紧密的循环中调用您的生成器,看看它是多么随机.