【问题标题】:How to generate 64 bit random numbers?如何生成 64 位随机数?
【发布时间】:2014-01-13 16:14:57
【问题描述】:

我正在实现通用哈希并使用以下通用哈希函数:

h(k)=((A*k)mod 2^64) rsh 64-r

其中A是一个随机数

2^61 和 2^62。

C++ 中的rand() 函数具有返回类型integer,它不能生成那么大的数字。那么如何在这个范围内生成随机数呢? (数字应该是非常随机的,即每个数字应该有相同的概率被选中)

注意:

long long int random=rand();

不起作用,因为 rand 返回的数字是 int

【问题讨论】:

  • 如果您手头有一个好的 PRNG(而不是 std::rand()),您可以从中生成 N 位并将它们连接起来。或者一次生成 M 位,并将它们连接起来。因为如果它好,每个位都有相同的概率,因此将它们连接起来是安全的。

标签: c++ random universal-hashing


【解决方案1】:

C++11 中,您可以使用 random headerstd::uniform_int_distribution 以及 64-bit instance of std::mersenne_twister_engine 这应该可以满足您的需求 (see it live) :

#include <iostream>
#include <random>
#include <cmath>

int main()
{
    std::random_device rd;

    std::mt19937_64 e2(rd());

    std::uniform_int_distribution<long long int> dist(std::llround(std::pow(2,61)), std::llround(std::pow(2,62)));

    std::cout << std::llround(std::pow(2,61)) << std::endl; 
    std::cout << std::llround(std::pow(2,62)) << std::endl; 

    for (int n = 0; n < 10; ++n) {
            std::cout << dist(e2)<< ", " ;
    }
    std::cout << std::endl ;
}

如果 C++11 不是一个选项,那么似乎有可用于several 64-bit Mersenne Twister implementations 的源代码。

【讨论】:

    【解决方案2】:
    ((long long)rand() << 32) | rand()
    

    编辑:假设 rand() 产生 32 个随机位,它可能不会。

    【讨论】:

    • 请注意,这实际上不会产生很好的结果。 (因为 std::rand 很糟糕)+1
    • 注意:在 RAND_MAX 是遗留的可怜的 0x7FFF 的垃圾 MS VC++ 环境中,这将不起作用。
    • @Whoz:这和我见过的所有其他实现一样糟糕。 std::rand 99.9% 的时间由某种描述的线性同余生成器提供支持——相比之下,它返回的范围是一个小问题。
    • @BillyONeal 如果受 0x7FFF 限制,在这种情况下这是一个巨大 问题,因为生成的数字不会在所需范围内根本 ,更不均匀分布在所述范围内(2^61..2^62)。
    • @BillyONeal 哦,我从来没有声称这是唯一阻止这个答案可行的事情。毫无疑问,我会像 Shafik 所做的那样实现这一点。我的观点是,这 依赖 RAND_MAX 的顶级范围,这并不总是人们认为的那样。但我当然也同意你的看法;即使高端是 0x7FFFFFFFF(因为它在大多数理智的 32 位 int 平台上除了 MS),这仍然会受到您描述的 LCG 的一致性问题的影响。
    猜你喜欢
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    相关资源
    最近更新 更多