Commit a282fdc9 authored by rtoy's avatar rtoy
Browse files


  Fix bug in deftransform where the case for x86 and num-high >
  random-fixnum-max was never used.  We now always use the bignum
  multiply code for all platforms and use that for all cases for which
  the deftransform applies.

  Simplify the constant-continuation case too so we don't have to the
  check.  I think the bignum multiply version does not have the bias
  problem that rem has.

  Change the RANDOM function to compute the same value as the
  deftransform would.


Make a note that both the function and the deftransform should be
synchronized to match.  This change also changes the sequence of
numbers produced.
parent 907b7746
......@@ -6,7 +6,7 @@
;;; placed in the Public domain, and is provided 'as is'.
"$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/code/rand-mt19937.lisp,v 1.15 2007/08/02 18:18:19 rtoy Exp $")
"$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/code/rand-mt19937.lisp,v 1.16 2008/06/24 17:27:51 rtoy Exp $")
;;; **********************************************************************
......@@ -443,8 +443,16 @@
(declare (inline %random-single-float %random-double-float
#+long-float %long-float))
((and (fixnump arg) (<= arg random-fixnum-max) (> arg 0))
(rem (random-chunk state) arg))
((typep arg '(integer 1 #x100000000))
;; Basically, pretend (random-chunk) produces a 32-bit fractional
;; number, multiply by arg, and take the integer part.
;; WARNING: If you change this be sure to make the deftransform
;; for RANDOM in float-tran.lisp does the same thing.
(if (= arg #x100000000)
(random-chunk state))
(values (bignum::%multiply (random-chunk state)
((and (typep arg 'single-float) (> arg 0.0F0))
(%random-single-float arg state))
((and (typep arg 'double-float) (> arg 0.0D0))
......@@ -5,7 +5,7 @@
;;; Carnegie Mellon University, and has been placed in the public domain.
"$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/float-tran.lisp,v 1.119 2008/04/08 14:15:35 rtoy Exp $")
"$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/float-tran.lisp,v 1.120 2008/06/24 17:27:51 rtoy Exp $")
;;; **********************************************************************
......@@ -248,29 +248,33 @@
:key #'numeric-type-high))
;; Rather than doing (rem (random-chunk) num-high), we do,
;; essentially, (rem (* num-high (random-chunk)) #x100000000). I
;; (rtoy) believe this approach doesn't have the bias issue with
;; doing rem. This method works by treating (random-chunk) as if
;; it were a 32-bit fraction between 0 and 1, exclusive. Multiply
;; this by num-high to get a random number between 0 and num-high,
;; This should have no bias.
;; WARNING: If you change this, be sure to look at the definition
;; of RANDOM so that it produces the same value as the
;; deftransform would produce.
(cond ((constant-continuation-p num)
;; Check the worst case sum abs error for the random number
;; expectations.
(let ((rem (rem (expt 2 32) num-high)))
(unless (< (/ (* 2 rem (- num-high rem)) num-high (expt 2 32))
(expt 2 (- kernel::random-integer-extra-bits)))
(give-up "The random number expectations are inaccurate."))
(if (= num-high (expt 2 32))
'(random-chunk (or state *random-state*))
#-x86 '(rem (random-chunk (or state *random-state*)) num)
;; Use multiplication which is faster.
'(values (bignum::%multiply
(random-chunk (or state *random-state*))
((> num-high random-fixnum-max)
(give-up "The range is too large to assure an accurate result."))
(if (= num-high (expt 2 32))
'(random-chunk (or state *random-state*))
'(values (bignum::%multiply
(random-chunk (or state *random-state*))
((< num-high (expt 2 32))
'(values (bignum::%multiply (random-chunk (or state *random-state*))
((= num-high (expt 2 32))
'(if (= num (expt 2 32))
(random-chunk (or state *random-state*))
(values (bignum::%multiply (random-chunk (or state *random-state*))
'(rem (random-chunk (or state *random-state*)) num)))))
(error "Shouldn't happen")))))
;;;; Float accessors:
......@@ -61,6 +61,11 @@ New in this release:
arglist contains items that can't be printed readably.
- DIRECTORY is now faster for directories with a large number of
- RANDOM is now much faster on all platforms for numbers near
#xffffffff. This is an incompatible change from previous
releases because the numbers produced may be different from
- The small bias in RANDOM should now be gone.
* Trac Tickets:
- #16: Read-time hash-table issue
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment