C 中高效的 32 位随机数生成器
Efficient 32 bit random number generator in C
我需要在 C 中生成几个 32 位随机数。为此我使用
4294967296.0*drand48()
效果很好。但它很慢。我可以使用其他更高效的发电机吗?
这是一个 Marsaglia xorshift 伪随机数生成器。周期为 2^160。在我的 AMD X64 上,每次迭代需要 6 个周期。那是每秒 3 亿个值。
在他的术语中,这是 [7,13,6] 版本。
您可以只使用两个种子来制作 2^64 PNRG,三个种子 2^96,四个种子 2^128。
最后一步不是 Marsaglia 论文的一部分;他只是 returns v。您可以通过连接种子来 return higher-precision 值。
我打电话给__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;
}
我需要在 C 中生成几个 32 位随机数。为此我使用
4294967296.0*drand48()
效果很好。但它很慢。我可以使用其他更高效的发电机吗?
这是一个 Marsaglia xorshift 伪随机数生成器。周期为 2^160。在我的 AMD X64 上,每次迭代需要 6 个周期。那是每秒 3 亿个值。
在他的术语中,这是 [7,13,6] 版本。
您可以只使用两个种子来制作 2^64 PNRG,三个种子 2^96,四个种子 2^128。
最后一步不是 Marsaglia 论文的一部分;他只是 returns v。您可以通过连接种子来 return higher-precision 值。
我打电话给__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;
}