objective-c – rand()如何工作?有某些倾向吗?有什么更好的使用吗?

前端之家收集整理的这篇文章主要介绍了objective-c – rand()如何工作?有某些倾向吗?有什么更好的使用吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经看到它与时间有关,你也可以从包含time.h中得到,所以我假设了很多,但是它如何正常工作?此外,它是否有任何倾向于奇数或偶数或类似的东西?最后是在C标准库还是Foundation框架中分布更好?

解决方法

简述:

>你使用time.h获得种子,这是一个初始随机数. C然后对这个数字做一堆操作来获取下一个随机数,然后在那个操作上获得下一个,然后…你得到的图片.
> rand()能够触摸每个可能的整数.不喜欢偶数或奇数,不管输入种子,愉快地.尽管如此,它还是有限制的 – 它相对快速地重复,几乎每个实现只能给出32767个数字.
> C没有另一个内置的随机生成器.如果您需要一个非常强硬的软件包,可以使用许多软件包,但Mersenne Twister算法可能是最受欢迎的选择.

现在,如果你对上述的原因感兴趣,这里是关于rand()的工作原理的详细信息:

rand()是所谓的“linear congruential generator.”这意味着它采用以下形式的等式:

xn 1 =(* a **** xn *** b *)mod m

其中xn是第n个随机数,a和b是一些预定的整数.算术执行模m,m通常为232,取决于机器,所以在xn 1的计算中只保留最低的32位.

在英文中,这个想法是这样的:要获取下一个随机数,将最后一个随机数乘以一个数字,向它添加一个数字,然后取最后几位数.

一些限制很明显:

>首先,你需要一个开始的随机数.这是你的随机数字生成器的“种子”,这是你听说过time.h被使用的地方.由于我们想要一个真正的随机数,通常的做法是询问系统什么时候是(以整数形式),并将其用作第一个“随机数”.此外,这也解释了为什么使用相同的种子两次将总是给出完全相同的随机数序列.这听起来很糟糕,但实际上是有用的,因为当您控制程序的输入时,调试更容易
>第二,a和b必须非常非常仔细地选择,否则你会得到一些灾难性的结果.幸运的是,线性同余发生器的方程很简单,数学已经得到了详细的阐述.事实证明,选择满足* a *** mod8 = 5以及*** b * = 1的一个将确保所有m个整数同样可能,而与种子的选择无关.你也想要一个值真的很大,所以每次你乘以xn你触发一个模数,并切断大量的数字,否则,一行中的许多数字将只是彼此的倍数.结果,根据Knuth,a(例如)的两个常见值是1566083941和1812433253. GNU C库恰好使用a = 1103515245和b = 12345. wikipedia page for LCGs提供了许多实现的值列表.
>第三,线性同余发生器将由于模数而实际重复.这可能是一些令人头痛的数学,但是这一切的结果是非常简单的:在生成m个数之后,序列将重复一遍.在大多数情况下,这意味着您的随机生成器将每232个周期重复一次.这听起来很多,但实际上并不适用于许多应用.如果您正在使用蒙特卡罗模拟进行严重的数字化工作,这个数字绝对不足.
>第四个不太明显的问题是数字实际上并不是随机的.他们有一个有趣的相关性.如果从一个值为a和m的LCG中取三个连续的整数(x,y,z),这三个点总是落在由三个点的所有线性组合生成的点的格子上(1,a,a2),(0,m,0),m).这就是Marsaglia的定理,如果你不明白,那没关系.所有这一切都是这样的:来自LCG的三倍数随机数将在一些深层次深层次显示相关性.通常,对于你或我来说,它太深了,但是它在那里.如果给予第二个和第三个,可以以三个数字的“随机”序列重建第一个数字!这根本不是密码学的好处.

很好的是,像兰德()这样的LCG非常非常低的占地面积.它通常只需要32位来保留状态,这是非常好的.它也很快,需要很少的操作.这些使它非常适合非关键的嵌入式系统,视频游戏,休闲应用程序,这样的东西.

PRNG是一个迷人的话题.如果您渴望了解更多关于历史或今天的各种实施方式,Wikipedia总是一个好地方.

猜你在找的C&C++相关文章