生成随机 64 位整数

发布于 2024-12-15 12:31:41 字数 257 浏览 1 评论 0原文

我需要你的帮助,请给我一些建议。从编程珍珠我知道,要生成随机 30 位整数,我们应该这样写:

RAND_MAX*rand()+rand()

但是我可以做什么来生成不是 30 位,而是 64 位随机整数呢?我认为如果我将两个30位整数相乘然后再乘以4位整数,这是非常低效的方法,那么我应该使用什么样的方法呢? 我现在正在使用 popcount_1 不同的 64 位方法,我想在随机整数上测试它(我还在测量每个方法完成任务所需的时间)

I need your help and please give me some advice. From programming pearls I know that to generate random 30 bit integer we should write it like this:

RAND_MAX*rand()+rand()

But what could I do for generating not 30, but 64 bit random integer instead? I think that is very inefficient method if I multiply two 30 bit integers and then multiply again 4 bit integer, so what kind of method should I use?
I am using now popcount_1 different method for 64 bit one and I would like to test it on random integers(I am also measuring the time which each one takes to accomplish the task)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清风疏影 2024-12-22 12:31:41

首先,我对您发布的 30 位解决方案表示怀疑
整数。 RAND_MAX 本身可以是一个 31 位值,并且 RAND_MAX *
rand() + rand()
可能会溢出,产生未定义的行为
(实际上,负值)。

如果您需要的值大于保证最小值 RAND_MAX,或者
就此而言,任何不明显小于
RAND_MAX,唯一的解决方案是使用连续调用
rand(),并组合这些值,但您需要小心地执行此操作,并且
验证结果。 (rand() 的大多数实现都使用线性
全等生成器虽然足以完成某些任务,但不能
在这种情况下特别好。)无论如何,类似:(

unsigned 
rand256()
{
    static unsigned const limit = RAND_MAX - RAND_MAX % 256;
    unsigned result = rand();
    while ( result >= limit ) {
        result = rand();
    }
    return result % 256;
}

unsigned long long
rand64bits()
{
    unsigned long long results = 0ULL;
    for ( int count = 8; count > 0; -- count ) {
        results = 256U * results + rand256();
    }
    return results;
}

rand256中的代码旨在消除其他情况
RAND_MAX 值映射到 256 个值时不可避免地会出现偏差。)

First, I have my doubts about the solution you post for a 30 bit
integer. RAND_MAX itself could be a 31 bit value, and RAND_MAX *
rand() + rand()
is likely to overflow, producing undefined behavior
(and in practice, negative values).

If you need a value larger than the guaranteed minimum of RAND_MAX, or
for that matter, anything that isn't significantly smaller than
RAND_MAX, the only solution will be to use successive calls to
rand(), and combine the values, but you need to do this carefully, and
validate the results. (Most implementations of rand() use linear
congruent generators, which while adequate for some tasks, aren't
particularly good in this case.) Anyway, something like:

unsigned 
rand256()
{
    static unsigned const limit = RAND_MAX - RAND_MAX % 256;
    unsigned result = rand();
    while ( result >= limit ) {
        result = rand();
    }
    return result % 256;
}

unsigned long long
rand64bits()
{
    unsigned long long results = 0ULL;
    for ( int count = 8; count > 0; -- count ) {
        results = 256U * results + rand256();
    }
    return results;
}

(The code in rand256 is designed to eliminate the otherwise
unavoidable bias you get when mapping RAND_MAX values to 256 values.)

往日情怀 2024-12-22 12:31:41

这可能是一个解决方案,无需乘法:

r30 = RAND_MAX*rand()+rand()
s30 = RAND_MAX*rand()+rand()
t4  = rand() & 0xf

res = (r30 << 34) + (s30 << 4) + t4

This could be a solution, without multiplication:

r30 = RAND_MAX*rand()+rand()
s30 = RAND_MAX*rand()+rand()
t4  = rand() & 0xf

res = (r30 << 34) + (s30 << 4) + t4
无畏 2024-12-22 12:31:41

如果 boost 是一个选项,您可以使用 增强随机

If boost is an option, you could use boost random.

冷默言语 2024-12-22 12:31:41

随机 64 位 int 本质上是解释为 int 的 64 个随机位。

用随机字节填充长度为 8 的字节数组 (请参见此处)并将它们解释为 int (请参阅此处了解具体方法)。

A random 64 bit int is essentially 64 random bits interpreted as an int.

Fill a byte array of length 8 with random bytes (see here for how) and interpret these as an int (see here for how).

枕梦 2024-12-22 12:31:41

通用解决方案:

template <unsigned long long I> struct log2 {
  static const int result = 1 + log2<I/2>::result;
};
template <> struct log2<1> {
  static const int result = 0;
};

template <typename UINT> UINT genrand() {
  UINT result = 0;
  int bits = std::numeric_limits<UINT>::digits;
  int rand_bits = log2<RAND_MAX>::result;
  while (bits > 0) {
    int r = rand();
    while (r >= (1<<rand_bits)) r = rand(); // Retry if too big.
    result <<= rand_bits;
    result += r;
    bits -= rand_bits;
  }
  return result;
}

使用:unsigned long long R = genrand();

位计数器跟踪仍需要的位数。

A generic solution:

template <unsigned long long I> struct log2 {
  static const int result = 1 + log2<I/2>::result;
};
template <> struct log2<1> {
  static const int result = 0;
};

template <typename UINT> UINT genrand() {
  UINT result = 0;
  int bits = std::numeric_limits<UINT>::digits;
  int rand_bits = log2<RAND_MAX>::result;
  while (bits > 0) {
    int r = rand();
    while (r >= (1<<rand_bits)) r = rand(); // Retry if too big.
    result <<= rand_bits;
    result += r;
    bits -= rand_bits;
  }
  return result;
}

Use: unsigned long long R = genrand<unsigned long long>();.

The bits counter keeps track of the number of bits still needed.

能怎样 2024-12-22 12:31:41

'返回 0 和 RAND_MAX 之间的伪随机积分值(包括 0 和 RAND_MAX)。' - http://en.cppreference.com/w/cpp/numeric/random /rand

所以你应该使用 RAND_MAX + 1 (这就像逐位生成一个数字,然后将其转换为基数 10)而不是 RAND_MAX。
通过这种方式,您可以生成以 RAND_MAX + 1 为基数(可能带有前导零)的一位、两位、三位等数字,并将它们转换为基数 10 并获得任意大的数字。

您获得的所有大于所需 MAX_VALUE 的内容都可以被丢弃,并且您仍然有 1/(MAX_VALUE + 1) 的概率获得每个数字。

请注意,此方法可能需要一段时间,特别是如果您所需的 MAX_VALUE 远小于丢弃不需要的数字之前可以获得的最大值,因为在 [0 中获取随机数的预期步骤数,MAX_VALUE]使用此算法为:(MAX_OBTAINABLE_VALUE + 1)/(MAX_VALUE + 1)

'Returns a pseudo-random integral value between ​0​ and RAND_MAX (0 and RAND_MAX included).' - http://en.cppreference.com/w/cpp/numeric/random/rand

So you should use RAND_MAX + 1 (it's like generating a number digit by digit and then converting it to base 10) instead of RAND_MAX.
This way you can generate numbers with one, two, three etc. digits in base RAND_MAX + 1(possibly with leading zeroes) and convert them to base 10 and get arbitrarily large numbers.

Everything that you obtain larger than your desired MAX_VALUE can be discarded and you still get 1/(MAX_VALUE + 1) probability for obtaining each number.

Note, that this method might take a while, especially if your desired MAX_VALUE is a lot less than the maximum value that can be obtained before discarding the numbers that are not desired, as the expected number of steps to obtain a random number in [0, MAX_VALUE] with this algorithm is: (MAX_OBTAINABLE_VALUE + 1)/(MAX_VALUE + 1)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文