emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 6fb45b7: * lisp/emacs-lisp/cl-extra.el (cl--random-


From: Stefan Monnier
Subject: [Emacs-diffs] master 6fb45b7: * lisp/emacs-lisp/cl-extra.el (cl--random-state): New defstruct
Date: Fri, 30 Jun 2017 22:01:45 -0400 (EDT)

branch: master
commit 6fb45b7b368c8041936c52f2b2c261136c070721
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    * lisp/emacs-lisp/cl-extra.el (cl--random-state): New defstruct
    
    (cl--random-state, cl--random-time): Move from cl-lib.el.
    (cl-random): Use struct accessors.
    (cl-random-state-p): Remove, provided by the defstruct.
    (cl-make-random-state): Rewrite to struct constructor.
---
 lisp/emacs-lisp/cl-extra.el | 39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index 3852ceb..99df209 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -437,22 +437,38 @@ as an integer unless JUNK-ALLOWED is non-nil."
 
 ;; Random numbers.
 
+(defun cl--random-time ()
+  (let* ((time (copy-sequence (current-time-string))) (i (length time)) (v 0))
+    (while (>= (cl-decf i) 0) (setq v (+ (* v 3) (aref time i))))
+    v))
+
+;;;###autoload (autoload 'cl-random-state-p "cl-extra")
+(cl-defstruct (cl--random-state
+               (:copier nil)
+               (:predicate cl-random-state-p)
+               (:constructor nil)
+               (:constructor cl--make-random-state (vec)))
+  (i -1) (j 30) vec)
+
+(defvar cl--random-state (cl--make-random-state (cl--random-time)))
+
 ;;;###autoload
 (defun cl-random (lim &optional state)
   "Return a 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 (aref state 3)))
+  (let ((vec (cl--random-state-vec state)))
     (if (integerp vec)
        (let ((i 0) (j (- 1357335 (abs (% vec 1357333)))) (k 1))
-         (aset state 3 (setq vec (make-vector 55 nil)))
+         (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 (aset state 1 (% (1+ (aref state 1)) 55)))
-          (j (aset state 2 (% (1+ (aref state 2)) 55)))
+    (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 (logand 8388607 (aset vec i (- (aref vec i) (aref vec j))))))
       (if (integerp lim)
          (if (<= lim 512) (% n lim)
@@ -466,17 +482,10 @@ Optional second arg STATE is a random-state object."
 (defun cl-make-random-state (&optional state)
   "Return a copy of random-state STATE, or of the internal state if omitted.
 If STATE is t, return a new state object seeded from the time of day."
-  (cond ((null state) (cl-make-random-state cl--random-state))
-       ((vectorp state) (copy-tree state t))
-       ((integerp state) (vector 'cl--random-state-tag -1 30 state))
-       (t (cl-make-random-state (cl--random-time)))))
-
-;;;###autoload
-(defun cl-random-state-p (object)
-  "Return t if OBJECT is a random-state object."
-  (and (vectorp object) (= (length object) 4)
-       (eq (aref object 0) 'cl--random-state-tag)))
-
+  (unless state (setq state cl--random-state))
+  (if (cl-random-state-p state)
+      (copy-tree state t)
+    (cl--make-random-state (if (integerp state) state (cl--random-time)))))
 
 ;; Implementation limits.
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]