【问题标题】:Efficient 32 bit random number generator in CC中的高效32位随机数生成器
【发布时间】:2022-02-02 18:22:13
【问题描述】:

我需要在 C 中生成几个 32 位随机数。为此我使用

4294967296.0*drand48()

效果很好。但它很慢。我可以使用其他更高效的生成器吗?

【问题讨论】:

  • 基本的rand() 函数至少生成15 位。您可以通过移位和屏蔽来组合一个 32 位的值。

标签: random


【解决方案1】:

这是一个 Marsaglia xorshift 伪随机数生成器。周期为 2^160。在我的 AMD X64 上,每次迭代需要 6 个周期。这是每秒 3 亿个值。

用他的术语来说,这是 [7,13,6] 版本。

你可以只用两个种子来制作一个 2^64 的 PNRG,2^96 用三个,2^128 用四个。

最后一步不是 Marsaglia 论文的一部分;他只是返回 v。您可以通过连接种子返回更高精度的值。

我打电话给__rdtsc() 只是为了提供一个随机种子。您可以使用不同的随机生成器来提供种子。


#include <stdio.h>
#include <intrin.h>

static unsigned long
    x=123456789,
    y=362436069,
    z=521288629,
    w=88675123,
    v=886756453;
/* replace defaults with five random seed values in calling program */

unsigned long xorshift(void)
{
    unsigned long t = x^(x>>7);
    x=y; y=z; z=w; w=v;
    v=(v^(v<<6))^(t^(t<<13)); 
    return (y+y+1)*v;
} 


// This is a period 2^32 PNRG ([13,17,5]), to fill the seeds.
// You can reverse all three shift directions, you can swap the 13 and 
// the 5, and you can move the 17 last, and it works equally well.
// Oddly, this takes 9 cycles on my box, compared to 6 for the longer
// period generator above.

unsigned long 
xorshift32(void)
{
    x ^= (x<<13);
    x ^= (x>>17);
    return x ^= (x<<5);
}

void
seed()
{
    x = (unsigned long) __rdtsc();
    v = xorshift32();
    w = xorshift32();
    z = xorshift32();
    y = xorshift32();
}

int
main()
{
    int i;
    seed();
    for( i = 0; i < 25; i++ )
        printf( "%08x\n", xorshift() );
    return 0;
}

【讨论】:

  • 非常感谢。我可以只返回 v 而不是 (y+y+1)*v 吗?
  • 何必担心呢?它少于 3 个 CPU 周期。我知道我有什么作品,我已经广泛使用它。正如我所说,最后一行不在 Marsaglia 的论文中,所以它可能也有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 2014-03-19
相关资源
最近更新 更多