我读到它与时间有关,你也可以从包含 time.h 中得到,所以我假设了这么多,但它到底是如何工作的呢?另外,它是否有奇数或偶数或类似数字的倾向?最后,C 标准库或 Foundation 框架中是否有更好的分布?
简要地:
You use time.h
得到一个种子,它是一个初始随机数。然后,C 对这个数字进行一系列操作以获得下一个随机数,然后对该数字进行操作以获得下一个随机数,然后......您就得到了图片。
rand()
能够触及每一个可能的整数。无论输入种子如何,它都不会喜欢偶数或奇数,很高兴。尽管如此,它还是有局限性——它的重复速度相对较快,并且在几乎每个实现中只能给出最多 32767 的数字。
C 没有另一个内置的随机数生成器。如果你需要一个真正困难的包,网上有很多包,但是梅森扭转者算法可能是最受欢迎的选择。
现在,如果您对原因感兴趣why上面是真的,这里是关于如何的血淋淋的细节rand()
works:
rand()
就是所谓的“线性同余发生器。”这意味着它采用以下形式的方程:
xn+1 = (*a****xn + ***b*) mod m
where xn is the nth random number, and a and b are some predetermined integers. The arithmetic is performed modulo m, with m usually 232 depending on the machine, so that only the lowest 32 bits are kept in the calculation of xn+1.
那么,在英语中,其想法是这样的:要获得下一个随机数,请将最后一个随机数乘以某个值,然后添加一个数字,然后取最后几位数字。
一些限制很快就会显现出来:
首先,您需要一个起始随机数。这是随机数生成器的“种子”,这就是您听说过的地方time.h
正在使用。由于我们想要一个真正的随机数,因此通常的做法是询问系统现在是什么时间(以整数形式)并将其用作第一个“随机数”。另外,这解释了为什么使用相同的种子两次会always give exactly相同的随机数序列。这听起来很糟糕,但实际上很有用,因为当您控制程序的输入时,调试会容易得多
Second, a and b have to be chosen very, very carefully or you'll get some disastrous results. Fortunately, the equation for a linear congruential generator is simple enough that the math has been worked out in some detail. It turns out that choosing an a which satisfies *a***mod8 = 5 together with ***b* = 1 will insure that all m integers are equally likely, independent of choice of seed. You also want a value of a that is really big, so that every time you multiply it by xn you trigger a the modulo and chop off a lot of digits, or else many numbers in a row will just be multiples of each other. As a result, two common values of a (for example) are 1566083941 and 1812433253 according to Knuth. The GNU C library happens to use a=1103515245 and b=12345. A list of values for lots of implementations is available at the wikipedia page for LCGs.
Third, the linear congruential generator will actually repeat itself because of that modulo. This gets to be some pretty heady math, but the result of it all is happily very simple: The sequence will repeat itself after m numbers of have been generated. In most cases, this means that your random number generator will repeat every 232 cycles. That sounds like a lot, but it really isn't for many applications. If you are doing serious numerical work with Monte Carlo simulations, this number is hopelessly inadequate.
A fourth much less obvious problem is that the numbers are actually not really random. They have a funny sort of correlation. If you take three consecutive integers, (x, y, z), from an LCG with some value of a and m, those three points will always fall on the lattice of points generated by all linear combinations of the three points (1, a, a2), (0, m, 0), (0, 0, m). This is known as Marsaglia's Theorem, and if you don't understand it, that's okay. All it means is this: Triplets of random numbers from an LCG will show correlations at some deep, deep level. Usually it's too deep for you or I to notice, but its there. It's possible to even reconstruct the first number in a "random" sequence of three numbers if you are given the second and third! This is not good for cryptography at all.
好的一点是 LCG 喜欢rand()
占地面积非常非常低。它通常只需要 32 位来保留状态,这非常好。它也非常快,需要很少的操作。这些使其非常适合非关键嵌入式系统、视频游戏、休闲应用程序等。
PRNG 是一个令人着迷的话题。维基百科如果您渴望了解更多有关历史或当今各种实现的信息,那么这始终是一个好地方。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)