阿然 发表于 2013-3-4 10:48
顶一个,调用dll的办法生成的随机数是最符合正态分布的,lisp在这方面确实比其他语言差。
Rnd [(number)] 函数
返回一个 Single 类型的随机数。
参数 Number 可选。一个 Single 值或任何有效的 Single 表达式。
返回值:
如果 Number 为 Rnd 生成
小于零 每次都相同的数字,并将 Number 用作种子。
大于零 序列中的下一个随机数。
等于零 最近生成的数字。
未提供 序列中的下一个随机数。
备注:
Rnd 函数返回小于 1 但大于或等于 0 的值。
Number 的值决定了 Rnd 生成随机数的方式。
由于每一次后续调用 Rnd 函数都用序列中前一个生成的数作为下一个数的种子,因此对于任何给定的初始种子都会生成相同的数字序列。
在调用 Rnd 之前,先使用无参数的 Randomize 语句初始化随机数生成器,该生成器具有一个基于系统计时器的种子。
随机函数可定义如下:
- (defun _Ran ()
- (vla-eval (vlax-get-acad-object) "Randomize : ThisDrawing.setVariable \"USERR5\" ,CDbl((Rnd))" )
- (getvar 'USERR5)
- )
注意:若要重复随机数序列,请在使用带数值参数的 Randomize 之前先调用带负参数的 Rnd。使用带有相同 Number 值的 Randomize 不会重复前一序列。
由于 Random 语句和 Rnd 函数从一个种子值开始,然后生成位于有限范围内的数字,因此,如果某个人知道生成这些数字的算法,他就可以预测结果。
因此,不应使用 Random 语句和 Rnd 函数生成加密使用的随机数。
请看下面的函数,用同一种子生成10个随机数,产生随机数序列始终是一样的:
- (defun c:tt (/ l)
- (vla-eval
- (vlax-get-acad-object)
- "Rnd (-2) : Randomize (10) "
- )
- (repeat 10
- (vla-eval (vlax-get-acad-object)
- " ThisDrawing.setVariable \"USERR5\" ,CDbl((Rnd))"
- )
- (setq l (cons (getvar 'userr5) l))
- )
- (princ (reverse l))
- (princ)
- )
运行 tt命令,始终返回如下序列数:
- '(0.175739 0.820543 0.0625842 0.494602 0.661623 0.958838 0.109856 0.216311 0.155918 0.74768)
|