;; @module whrandom.lsp ;; @author Cyril Slobin ;; @description Wichman-Hill random number generator ;; ;; Derived from the 'random.py' module (Python standard library) ;; ;; The period of this generator is 6,953,607,871,644 ;; ;; Note that Python itself has obsoleted Wichman-Hill and ;; substituted it with Mersenne Twister since version 2.3 ;; ;; XXX Not complete yet, pre-alpha stage XXX (context 'wh) (define-macro (define-multi header) (letex ((Newheader (append header '(_n))) (Self header) (Body (cons 'begin (args)))) (define Newheader (if (null? _n) Body (let (_acc '()) (dotimes (i _n) (push Self _acc -1)) _acc))))) (setq x 1 y 1 z 1) (define (random-one) (setq x (% (* 171 x) 30269)) (setq y (% (* 172 y) 30307)) (setq z (% (* 170 z) 30323)) (mod (add (div x 30269.0) (div y 30307.0) (div z 30323.0)) 1.0)) (define (wh:seed n) (setq x (+ 1 (% n 30268)) n (/ n 30268)) (setq y (+ 1 (% n 30306)) n (/ n 30306)) (setq z (+ 1 (% n 30322)) n (/ n 30322))) (define-multi (wh:rand range) (if (zero? range) (wh:seed (+ (* (date-value) 1024) (% (time-of-day) 1024))) (int (mul range (random-one))))) (define-multi (wh:random offset scale) (add offset (mul scale (random-one)))) (context MAIN)