可能重复:
随机数发生器如何工作?
我正在寻找C / C ++中随机数生成器的内部实现。基本上我很想知道调用rand()时究竟发生了什么。 在所有机器遵循一套明确的指令后,它怎么可能是随机的!
编辑:想知道如何在C / C ++中实现一个。
它们是伪随机数生成器,而不是真正随机生成器。 这通常是一件好事,因为它允许您更容易地在涉及“随机”数字的情况下重现错误。
您可以获得随机数生成器,例如在Linux下读取/dev/random
,但通常不附带C库的正常生成器。
最简单的是线性同余生成器,其中:
n(x+1) = n(x) * A + C modulo M
适当选择的A
, C
和M
。
维基百科关于LCG的页面给出了各种实现使用的一些示例值。 例如,那里列出的glibc
有a = 1103515245, c = 12345, m = 2^31
所以这很简单:
static unsigned int seed = 1; void srand (int newseed) { seed = (unsigned)newseed & 0x7fffffffU; } int rand (void) { seed = (seed * 1103515245U + 12345U) & 0x7fffffffU; return (int)seed; }
旁白:glibc实现仍然在其中有这个生成器(称为类型0生成器),但它也有一个更高级的三项式生成器,(可能)更好。
还有更复杂的(例如梅森捻线机)具有更长的循环时间(开始重复之前的时间)。
任何真正随机的生成器必须使用真正的随机输入源,这就是/dev/random
有时会阻塞(“等待熵”)而/dev/urandom
不会。
“真正的”随机源可能会受到键击之间的时间,数据输入的数据,网络数据包的内容,磁盘I / O模式,ICMP响应通过网络返回所需的时间以及各种其他奇妙的影响。非确定性的东西。
除非你非常重视加密,否则正常的随机数生成器就可以了。
正如我在评论中所说,RAM机器的随机生成器不是真正随机的,它们是伪随机的 。
您可以随时查看java.util.Random的java源代码。
具体来说 – 方法next(int bits)
就是你要找的。
protected int next(int bits) { long oldseed, nextseed; AtomicLong seed = this.seed; do { oldseed = seed.get(); nextseed = (oldseed * multiplier + addend) & mask; } while (!seed.compareAndSet(oldseed, nextseed)); return (int)(nextseed >>> (48 - bits)); }
(*)这个答案适用于问题的先前版本,该问题被标记为java并且没有专门针对C ++。
这是一个简单的伪随机算法:
//generates pseudo random series of numbers 0...RAND_MAX - 1 with uniform distribution, starting with 0 static const int A = 15342; // any number in (0, RAND_MAX) static const int C = 45194; // any number in [0, RAND_MAX) static const RAND_MAX = 100000; int rand() { static int prev = 0; //seed. any number in [0, RAND_MAX) prev = ( prev * A + C ) % RAND_MAX; return prev; }
您可以在这里阅读更多内容: http : //en.wikipedia.org/wiki/Linear_congruential_generator
我认为数字收件簿是一个很好的起点。
以上就是c/c++开发分享随机数发生器的实现相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/541867.html