0

一段时间以来,我一直在使用 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编译。

方法 :

  1. 启动 Powershell 命令提示符
  2. 加载我的程序集Add-Type -Path <mydll>
  3. 调用[rdrw.Random]::Next(4)
  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;
        }
    };
}

感谢您的见解!

4

0 回答 0