Re: Random generator

Bernd Beuster <[email protected]> Sat, 1 Sep 2007 17:08:24 +0200
Newsgroups gmane.lisp.openmcl.bugs
Message-ID <[email protected]>
The previous patch did not lead to correct random numbers. The reason  
is that %next-random-pair seems not to be correct implemented.

I think on a x86-64 machine the division by 2^31-1 is fast enough.

This is a proof of concept implementation, what gives the correct  
results in both cases:


(let ((ccl::*warn-if-redefine-kernel* nil))
   (setf *random-state* 1) ; has to be > 0

   (defun random (number &optional (state *random-state*))
     ;; implementation with division
     (setf *random-state* (mod (* 48271 state) #.(1- (expt 2 31))))

     ;; implemention without division (not faster on x86-64)
     #+or(let* ((ab  (* 48271 state))
	   (u   (ldb (byte 31 0) ab))
	   (v   (ldb (byte 31 31) ab))
	   (u+v (+ u v)))
       (setf *random-state* (if (< u+v #.(expt 2 31))
			       u+v
			       (1+ (ldb (byte 31 0) u+v)))))

     (mod *random-state* number)))



Anyway, this random generator is not very good and should be replaced  
by a better one, e.g. Mersenne-Twister or Yarrow.


-- 
Bernd