[英]Analysis of Linear congruential generator is wrong?
So in an attempt to better understand MSVC++'s implementation of rand
, I re-implemented it and attempted to better understand it (and LCGs in general I guess). 因此,为了更好地理解MSVC ++的
rand
实现,我重新实现了它,并试图更好地理解rand
(我想大概是LCG)。
My implementation (which matches MSVC++'s almost exactly) is as follows: 我的实现(几乎与MSVC ++完全匹配)如下:
// vc++ impl. of random
// Xn+1 = (aXn + i) mod m
// a = 214013, i = 2531011, m = 32768
unsigned int seed = 0;
unsigned int random()
{
seed = seed * 214013L + 2531011L;
// return (seed/(1<<16)) % 32768; (equiv to below)
return seed>>16 & 0x7FFF;
}
To find the difference in the newly generated seeds from 2 seeds, I figured it would just be (214013*h) % 2^32
where h is the difference between the 2 initial seeds. 为了找出2个种子中新生成的种子之间的差异,我计算出这只是
(214013*h) % 2^32
,其中h是2个初始种子之间的差异。 Using this same logic I figured the difference between 2 randomly generated numbers given the initial seed as x
and the next seed as x+h
, I took this different in seed, divided it by 2^16 (or shifted it right 16 bits), and got rid of the most significant bit. 使用相同的逻辑,我计算出在给定初始种子为
x
和下一个种子为x+h
,随机产生的两个数字之间的差,我将其取为2 ^ 16(或右移16位)除以种子的不同,并摆脱了最重要的部分。
The values this yields seem to be correct except in some cases, for example when x = 100 and h = 5000. 除非在某些情况下(例如,当x = 100且h = 5000时),否则此得出的值似乎是正确的。
Here's the entire code: 这是完整的代码:
#include <iostream>
#include <cstdlib>
// vc++ impl. of random
// Xn+1 = (aXn + i) mod m
// a = 214013, i = 2531011, m = 32768
unsigned int seed = 0;
unsigned int random()
{
seed = seed * 214013L + 2531011L;
return seed>>16 & 0x7FFF;
}
int main()
{
// f(x) = (214013x + 2531011) mod 2^32 [LCG]
// g(x) = floor(f(x)/2^16) mod 2^15 [RND]
// h(x) = f(x + h) - f(x) ?= 214013*h mod 2^32
// j(x) = g(x + h) - g(x) ?= 214013*h/2^16 mod 2^15
// x: initial seed
// h: displaecment to next seed (next seed: x + h)
// a, b: first and second randomly generated values using C rand
// c, d: first and second randomly generated values using random
// newSeedA, newSeedB: seed generated from LCG after x and x + h respectively
// diffExp: experimental difference in random values
// diffCalc: calculated/theoretical difference in random vlaues
unsigned int x = 100, h = 50000;
unsigned int a, b, c, d;
unsigned int newSeedA, newSeedB;
int diffExp, diffCalc;
srand(x);
seed = x;
a = rand();
c = random();
newSeedA = seed;
srand(x + h);
seed = x + h;
b = rand();
d = random();
newSeedB = seed;
diffExp = (d - c) % 32768;
diffCalc = (214013*h)>>16 & 0x7FFF;
std::cout << "RANDOM VALUES\n";
std::cout << " VC++ rand: " << a << ", " << b << "\n";
std::cout << "Custom rand: " << c << ", " << d << "\n";
std::cout << "\n";
std::cout << "DIFFERENCE IN SEED\n";
std::cout << "Experimental Difference: " << (newSeedB - newSeedA) << "\n";
std::cout << " Calculated Difference: " << (static_cast<unsigned int>(214013)*h) << "\n";
std::cout << "\n";
std::cout << "DIFFERENCE IN VALUES\n";
std::cout << "Experimental Difference: " << diffExp << "\n";
std::cout << " Calculated Difference: " << diffCalc << "\n";
std::cout << "\n";
return 0;
}
However with these values, the estimated difference between the 2 randomly generated values is 1 less than the actual difference. 但是,使用这些值,两个随机生成的值之间的估计差异比实际差异小1。 Am I doing something obviously wrong?
我做错了什么吗?
The difference between the new seeds is indeed 214013*h
. 新种子之间的差异确实为
214013*h
。
That gives the seeds s
and s + 214013*h
, the difference between the resulting random outputs would be (before simplification) diff = ((s + 214013*h >> 16) & 0x7fff) - ((s >> 16) & 0x7fff)
. 得出种子
s
和s + 214013*h
,结果随机输出之间的差为(简化之前) diff = ((s + 214013*h >> 16) & 0x7fff) - ((s >> 16) & 0x7fff)
。 The question is then essentially, is this expression independent of s
. 那么本质上的问题是,该表达式是否独立于
s
。
It is not. 它不是。 For example, even taking
h = 1
, diff
can be either 3 (eg s = 0
) or 4 (eg s = 0x0000bc03
). 例如,即使取
h = 1
, diff
也可以是3(例如s = 0
)或4(例如s = 0x0000bc03
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.