Function: cl-random

cl-random is an autoloaded and byte-compiled function defined in cl-extra.el.gz.

Signature

(cl-random LIM &optional STATE)

Documentation

Return a pseudo-random nonnegative number less than LIM, an integer or float.

Optional second arg STATE is a random-state object.

Aliases

random* (obsolete since 27.1)

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/cl-extra.el.gz
;;;###autoload
(defun cl-random (lim &optional state)
  "Return a pseudo-random nonnegative number less than LIM, an integer or float.
Optional second arg STATE is a random-state object."
  (or state (setq state cl--random-state))
  ;; Inspired by "ran3" from Numerical Recipes.  Additive congruential method.
  (let ((vec (cl--random-state-vec state)))
    (if (integerp vec)
	(let ((i 0) (j (- 1357335 (abs (% vec 1357333)))) (k 1))
	  (setf (cl--random-state-vec state)
                (setq vec (make-vector 55 nil)))
	  (aset vec 0 j)
	  (while (> (setq i (% (+ i 21) 55)) 0)
	    (aset vec i (setq j (prog1 k (setq k (- j k))))))
	  (while (< (setq i (1+ i)) 200) (cl-random 2 state))))
    (let* ((i (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-i state)))
	   (j (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-j state)))
	   (n (aset vec i (logand 8388607 (- (aref vec i) (aref vec j))))))
      (if (integerp lim)
	  (if (<= lim 512) (% n lim)
	    (if (> lim 8388607) (setq n (+ (ash n 9) (cl-random 512 state))))
	    (let ((mask 1023))
	      (while (< mask (1- lim)) (setq mask (1+ (+ mask mask))))
	      (if (< (setq n (logand n mask)) lim) n (cl-random lim state))))
	(* (/ n '8388608e0) lim)))))