Robert Maas, <jaycx2.3.calrobert@spamgourmet.com.remove> wrote:
+---------------
| Hey, because you deleted part of my address, namely the 'uh3t' part...
+---------------
It makes the line too long, and anyway, "tinyurl.com" isn't
"part of [your] address".
+---------------
| > There's special code on X86 platforms to allow args up to (EXPT 2 32),
| > *significantly* larger than KERNEL:RANDOM-FIXNUM-MAX [== 4194303 in 19c,
| > but see below re 18b!], but unfortunately the COND branch for that check
| > is in the wrong place!! [Yes, I have already mentioned this to one of
| > the CMUCL maintainers.]
|
| Is there a patch for that which generates a FASL file which can be
| loaded into the user's environment to temporarily fix the problem
| without needing sysadmin access to re-install the CMUCL core image?
+---------------
Yes, that's how I tested it. Simply COMPILE-FILE the following
[snip between the "===" lines] and load it into your running image:
===== BEGIN "float-tran-patch.lisp" ===================
(in-package "C")
#+random-mt19937
(deftransform random ((num &optional state)
((integer 1 #.(expt 2 32)) &optional *))
"use inline (unsigned-byte 32) operations"
(let* ((num-type (continuation-type num))
(num-high (cond ((numeric-type-p num-type)
(numeric-type-high num-type))
((union-type-p num-type)
;; Find the maximum of the union type. We
;; know this works because if we're in this
;; routine, NUM must be a subtype of
;; (INTEGER 1 2^32), so each member of the
;; union must be a subtype too.
(reduce #'max (union-type-types num-type)
:key #'numeric-type-high))
(t
(give-up)))))
(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)
#+x86
;; Use multiplication which is faster.
'(values (bignum::%multiply
(random-chunk (or state *random-state*))
num)))))
;; 2008-06-20/rpw3@rpw3.org -- BUGFIX! Swapped next two cases.
#+x86
((< num-high (expt 2 32))
'(values (bignum::%multiply (random-chunk (or state *random-state*))
num)))
((> num-high random-fixnum-max)
(give-up "The range is too large to assure an accurate result."))
(t
'(rem (random-chunk (or state *random-state*)) num)))))
===== END "float-tran-patch.lisp" ===================
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607