一段时间以来,我一直在使用 Intel 提供的 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, 3, 1, 3、3、3、3。
1 的数量:6 2 的数量:9 3 的数量:12 4 的数量:2 总计:29
我实际上想知道英特尔的 RNG、我的算法、方法或其他问题是否存在问题?还是您认为偏见还不够显着?
我使用的是 Windows 10 Pro,我的 CPU 是 Intel Core i7-4710MQ。用VS2017编译。
方法 :
- 启动 Powershell 命令提示符
- 加载我的程序集
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;
}
};
}
感谢您的见解!