+2012-09-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Better seed support for (random).
+ * numbers.texi (Random Numbers): Document new behavior of
+ the calls (random) and (random STRING).
+
2012-08-21 Martin Rudalics <rudalics@gmx.at>
* windows.texi (Window Point): Document recent changes in
mimic a random series. For example, all possible values occur equally
often in a pseudo-random series.
-In Emacs, pseudo-random numbers are generated from a ``seed'' number.
+In Emacs, pseudo-random numbers are generated from a ``seed''.
Starting from any given seed, the @code{random} function always
-generates the same sequence of numbers. Emacs always starts with the
-same seed value, so the sequence of values of @code{random} is actually
-the same in each Emacs run! For example, in one operating system, the
-first call to @code{(random)} after you start Emacs always returns
-@minus{}1457731, and the second one always returns @minus{}7692030. This
-repeatability is helpful for debugging.
-
-If you want random numbers that don't always come out the same, execute
-@code{(random t)}. This chooses a new seed based on the current time of
-day and on Emacs's process @acronym{ID} number.
+generates the same sequence of numbers. Emacs typically starts with a
+different seed each time, so the sequence of values of @code{random}
+typically differs in each Emacs run.
+
+Sometimes you want the random number sequence to be repeatable. For
+example, when debugging a program whose behavior depends on the random
+number sequence, it is helpful to get the same behavior in each
+program run. To make the sequence repeat, execute @code{(random "")}.
+This sets the seed to a constant value for your particular Emacs
+executable (though it may differ for other Emacs builds). You can use
+other strings to choose various seed values.
@defun random &optional limit
This function returns a pseudo-random integer. Repeated calls return a
series of pseudo-random integers.
If @var{limit} is a positive integer, the value is chosen to be
-nonnegative and less than @var{limit}.
+nonnegative and less than @var{limit}. Otherwise, the value
+might be any integer representable in Lisp.
If @var{limit} is @code{t}, it means to choose a new seed based on the
current time of day and on Emacs's process @acronym{ID} number.
-On some machines, any integer representable in Lisp may be the result
-of @code{random}. On other machines, the result can never be larger
-than a certain maximum or less than a certain (negative) minimum.
+If @var{limit} is a string, it means to choose a new seed based on the
+string's contents.
+
@end defun
+2012-09-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Better seeds for (random).
+ * NEWS: Document new behavior of (random), (random "string").
+
2012-08-28 Andreas Schwab <schwab@linux-m68k.org>
* charsets/MULE-ethiopic.map: Fix typo in comment.
\f
* Incompatible Lisp Changes in Emacs 24.3
+** (random) by default now returns a different random sequence in
+every Emacs run. Use (random S), where S is a string, to set the
+random seed to a value based on S, in order to get a repeatable
+sequence in later calls.
+
** The function `x-select-font' can return a font spec, instead of a
font name as a string. Whether it returns a font spec or a font name
depends on the graphical library.
+2012-09-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Better seed support for (random).
+ * play/5x5.el, play/animate.el, play/cookie1.el, play/dissociate.el:
+ * play/doctor.el, play/dunnet.el, play/gomoku.el, play/landmark.el:
+ * play/mpuz.el, play/tetris.el, play/zone.el:
+ * calc/calc-comb.el (math-init-random-base):
+ * play/blackbox.el (bb-init-board):
+ * play/life.el (life):
+ * server.el (server-use-tcp):
+ * type-break.el (type-break):
+ Remove unnecessary call to (random t).
+ * net/sasl.el (sasl-unique-id-function):
+ Change (random t) to (random), now that the latter is more random.
+ * play/life.el (life-initialized): Remove no-longer-needed var.
+
2012-08-31 Alp Aker <alp.tekin.aker@gmail.com>
* window.el (switch-to-prev-buffer, switch-to-next-buffer):
;; (time-trial
;; '(let ((size 10000)
;; doing)
-;; (random t)
;; (dotimes (count size)
;; (setq doing (random size))
;; (funcall try doing (+ doing (random 5)))
4877 4889 4903 4909 4919 4931 4933 4937 4943 4951 4957 4967 4969 4973
4987 4993 4999 5003])
-;; The variable math-prime-factors-finished is set by calcFunc-prfac to
+;; The variable math-prime-factors-finished is set by calcFunc-prfac to
;; indicate whether factoring is complete, and used by calcFunc-factors,
;; calcFunc-totient and calcFunc-moebius.
(defvar math-prime-factors-finished)
(while (<= (length math-stirling-local-cache) n)
(let ((i (1- (length math-stirling-local-cache)))
row)
- (setq math-stirling-local-cache
- (vconcat math-stirling-local-cache
+ (setq math-stirling-local-cache
+ (vconcat math-stirling-local-cache
(make-vector (length math-stirling-local-cache) nil)))
(aset math-stirling-cache k math-stirling-local-cache)
(while (< (setq i (1+ i)) (length math-stirling-local-cache))
(let ((i 200))
(while (> (setq i (1- i)) 0)
(math-random-base))))
- (random t)
(setq var-RandSeed nil
math-random-cache nil
math-random-shift -4) ; assume RAND_MAX >= 16383
(i (/ (+ n slop) 3))
(rnum 0))
(while (> i 0)
- (setq rnum
+ (setq rnum
(math-add
(math-random-three-digit-number)
(math-mul rnum 1000)))
(setq sum (%
(+
sum
- (calcFunc-mod
+ (calcFunc-mod
q 1000000))
111111))
- (setq q
- (math-quotient
+ (setq q
+ (math-quotient
q 1000000)))
(cond ((= (% sum 3) 0) '(nil 3))
((= (% sum 7) 0) '(nil 7))
+2012-09-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Better seeds for (random).
+ * gnus-sync.el (gnus-sync-lesync-setup):
+ * message.el (message-canlock-generate, message-unique-id):
+ Change (random t) to (random), now that the latter is more random.
+
2012-08-31 Dave Abrahams <dave@boostpro.com>
* auth-source.el (auth-sources): Fix macos keychain access.
(security-object (concat url "/_security"))
(user-record `((names . [,user]) (roles . [])))
(couch-user-name (format "org.couchdb.user:%s" user))
- (salt (or salt (sha1 (format "%s" (random t)))))
+ (salt (or salt (sha1 (format "%s" (random)))))
(couch-user-record
`((_id . ,couch-user-name)
(type . user)
(require 'sha1)
(let (sha1-maximum-internal-length)
(sha1 (concat (message-unique-id)
- (format "%x%x%x" (random)
- (progn (random t) (random))
- (random))
+ (format "%x%x%x" (random) (random) (random))
(prin1-to-string (recent-keys))
(prin1-to-string (garbage-collect))))))
;; You might for example insert a "." somewhere (not next to another dot
;; or string boundary), or modify the "fsf" string.
(defun message-unique-id ()
- (random t)
;; Don't use microseconds from (current-time), they may be unsupported.
;; Instead we use this randomly inited counter.
(setq message-unique-id-char
;; Don't use microseconds from (current-time), they may be unsupported.
;; Instead we use this randomly inited counter.
(setq sasl-unique-id-char
- (% (1+ (or sasl-unique-id-char (logand (random t) (1- (lsh 1 20)))))
+ (% (1+ (or sasl-unique-id-char (logand (random) (1- (lsh 1 20)))))
;; (current-time) returns 16-bit ints,
;; and 2^16*25 just fits into 4 digits i base 36.
(* 25 25)))
+2012-09-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Better seed support for (random).
+ * org-id.el (org-id-uuid):
+ Change (random t) to (random), now that the latter is more random.
+
2012-07-29 Paul Eggert <eggert@cs.ucla.edu>
Don't use the abbreviation "win" to refer to Windows (Bug#10421).
(defun org-id-uuid ()
"Return string with random (version 4) UUID."
(let ((rnd (md5 (format "%s%s%s%s%s%s%s"
- (random t)
+ (random)
(current-time)
(user-uid)
(emacs-pid)
(y-or-n-p prompt)
t))
-(random t)
-
(provide '5x5)
;;; 5x5.el ends here
(animate-string "my sunshine" 18 34)
(animate-string "to stay!" 19 34))
-(random t)
-
(provide 'animate)
;;; animate.el ends here
(define-key map (vector 'remap oldfun) newfun))
-(defvar blackbox-mode-map
+(defvar blackbox-mode-map
(let ((map (make-keymap)))
(suppress-keymap map t)
(blackbox-redefine-key map 'backward-char 'bb-left)
(bb-goto (cons bb-x bb-y)))
(defun bb-init-board (num-balls)
- (random t)
(let (board pos)
(while (>= (setq num-balls (1- num-balls)) 0)
(while
;;; Code:
-; Randomize the seed in the random number generator.
-(random t)
-
(defconst cookie-delimiter "\n%%\n\\|\n%\n\\|\0"
"Delimiter used to separate cookie file entries.")
(funcall search-function overlap opoint t))))))
(sit-for 0))))
-(random t)
-
(provide 'dissociate)
;;; dissociate.el ends here
(defun doctor-chat () (doctor-type (doc$ doctor--chatlst)))
-(random t)
-
(provide 'doctor)
;;; doctor.el ends here
(dun-uexit nil)))
-(random t)
(setq tloc (+ 60 (random 18)))
(dun-replace dun-room-objects tloc
(append (nth tloc dun-room-objects) (list 18)))
(move-to-column (+ gomoku-x-offset
(* gomoku-square-width (1- gomoku-board-width)))))
-(random t)
-
(provide 'gomoku)
;;; gomoku.el ends here
;;;allout-layout: (0 : -1 -1 0)
;;;End:
-(random t)
-
(provide 'landmark)
;;; landmark.el ends here
;; Sadly, mode-line-format won't display numbers.
(defvar life-generation-string nil)
-(defvar life-initialized nil
- "Non-nil if `life' has been run at least once.")
-
;;;###autoload
(defun life (&optional sleeptime)
"Run Conway's Life simulation.
arg non-nil from a program) is the number of seconds to sleep between
generations (this defaults to 1)."
(interactive "p")
- (or life-initialized
- (random t))
- (setq life-initialized t)
(or sleeptime (setq sleeptime 1))
(life-setup)
(catch 'life-exit
:prefix "mpuz-"
:group 'games)
-(random t) ; randomize
-
(defcustom mpuz-silent 'error
"Set this to nil if you want dings on inputs.
The value t means never ding, and `error' means only ding on wrong input."
(tetris-mode)
(tetris-start-game))
-(random t)
-
(provide 'tetris)
;;; tetris.el ends here
(kill-buffer nil))))
-(random t)
-
;;;;;;;;;;;;;;;
(provide 'zone)
(setq val t)
(unless load-in-progress
(message "Local sockets unsupported, using TCP sockets")))
- (when val (random t))
(set-default sym val))
:group 'server
:type 'boolean
(unless type-break-terse-messages
(message "Press any key to resume from typing break."))
- (random t)
(let* ((len (length type-break-demo-functions))
(idx (random len))
(fn (nth idx type-break-demo-functions)))
+2012-09-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Better seed support for (random).
+ * emacs.c (main): Call init_random.
+ * fns.c (Frandom): Set the seed from a string argument, if given.
+ Remove long-obsolete Gentzel cruft.
+ * lisp.h, sysdep.c (seed_random): Now takes address and size, not long.
+ (init_random): New function.
+
2012-08-31 Dmitry Antipov <dmantipov@yandex.ru>
Remove mark_ttys function and fix tty_display_info initialization.
init_data ();
init_atimer ();
running_asynch_code = 0;
+ init_random ();
no_loadup
= argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
(Lisp_Object limit)
{
EMACS_INT val;
- Lisp_Object lispy_val;
if (EQ (limit, Qt))
- {
- EMACS_TIME t = current_emacs_time ();
- seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t));
- }
+ init_random ();
+ else if (STRINGP (limit))
+ seed_random (SSDATA (limit), SBYTES (limit));
+ val = get_random ();
if (NATNUMP (limit) && XFASTINT (limit) != 0)
- {
- /* Try to take our random number from the higher bits of VAL,
- not the lower, since (says Gentzel) the low bits of `random'
- are less random than the higher ones. We do this by using the
- quotient rather than the remainder. At the high end of the RNG
- it's possible to get a quotient larger than n; discarding
- these values eliminates the bias that would otherwise appear
- when using a large n. */
- EMACS_INT denominator = (INTMASK + 1) / XFASTINT (limit);
- do
- val = get_random () / denominator;
- while (val >= XFASTINT (limit));
- }
- else
- val = get_random ();
- XSETINT (lispy_val, val);
- return lispy_val;
+ val %= XFASTINT (limit);
+ return make_number (val);
}
\f
/* Heuristic on how many iterations of a tight loop can be safely done
extern void setup_pty (int);
extern int set_window_size (int, int, int);
extern EMACS_INT get_random (void);
-extern void seed_random (long);
+extern void seed_random (void *, ptrdiff_t);
+extern void init_random (void);
extern int emacs_open (const char *, int, int);
extern int emacs_close (int);
extern ptrdiff_t emacs_read (int, char *, ptrdiff_t);
#endif /* !RAND_BITS */
void
-seed_random (long int arg)
+seed_random (void *seed, ptrdiff_t seed_size)
{
+#if defined HAVE_RANDOM || ! defined HAV_LRAND48
+ unsigned int arg = 0;
+#else
+ long int arg = 0;
+#endif
+ unsigned char *argp = (unsigned char *) &arg;
+ unsigned char *seedp = seed;
+ ptrdiff_t i;
+ for (i = 0; i < seed_size; i++)
+ argp[i % sizeof arg] ^= seedp[i];
#ifdef HAVE_RANDOM
- srandom ((unsigned int)arg);
+ srandom (arg);
#else
# ifdef HAVE_LRAND48
srand48 (arg);
# else
- srand ((unsigned int)arg);
+ srand (arg);
# endif
#endif
}
+void
+init_random (void)
+{
+ EMACS_TIME t = current_emacs_time ();
+ uintmax_t v = getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t);
+ seed_random (&v, sizeof v);
+}
+
/*
* Return a nonnegative random integer out of whatever we've got.
* It contains enough bits to make a random (signed) Emacs fixnum.