一段时间以来,我一直在使用英特尔提供的RNG功能,通过自己编写的C ++ / CLI程序为自己提供一些随机性。
但是,过了一段时间,有些事情让我感到特别可疑。在其他用途中,我要求输入1到4之间的一个随机数,然后每次将结果记录在纸上。结果如下:
2、3、3、2、1、3、4、2、3、2、3、1、3、2、3、1、2、4、2、2、1、2、1、1、3 ,1、3、3、3、3。
1的个数:6 2秒数:9 3秒数:12 4s数:2 总计:29
我实际上是在想英特尔的RNG,我的算法,方法论还是其他问题?还是您认为偏差还不够大?
我正在使用Windows 10 Pro,我的CPU是Intel Core i7-4710MQ。 与VS2017一起编译。
方法:
Add-Type -Path <mydll>
加载我的程序集[rdrw.Random]::Next(4)
一个可能很重要的细节:我并不经常要求这个数字,所以两次抽奖之间会有一段时间,通常是RNG一段时间没有使用(至少一个小时)。
是的,这是一个惰性算法,我不想因异常而困扰自己。
算法如下:
#include <immintrin.h>
namespace rdrw {
#pragma managed(push,off)
unsigned long long getRdRand() {
unsigned long long val = 0;
while (!_rdrand64_step(&val));
return val;
}
#pragma managed(pop)
public ref class Random abstract sealed
{
public:
// Returns a random 64 bit unsigned integer
static unsigned long long Next() {
return getRdRand();
}
// Return a random unsigned integer between 0 and max-1 (inclusive)
static unsigned long long Next(unsigned long long max) {
unsigned long long nb = max - 1;
unsigned long long mask = 1;
unsigned long long draw = 0;
if (max <= 1)
return 0;
// Create a bitmask that's at least as big as the biggest acceptable value
while ((nb&mask) != nb)
{
mask <<= 1;
mask |= 1;
}
do
{
// Throw unnecessary bits
draw = Next() & mask;
} while (draw>nb);
return draw;
}
// return a random unsigned integer between min and max-1 inclusive
static unsigned long long Next(unsigned long long min, unsigned long long max) {
if (max == min)
return min;
if (max < min)
return 0;
unsigned long long diff = max - min;
return Next(diff) + min;
}
};
}
感谢您的见解!