Raymond Toy pushed to branch master at cmucl / cmucl

Commits:

2 changed files:

Changes:

  • src/bootfiles/21e/boot-2023-08.lisp
    ... ... @@ -2,3 +2,46 @@
    2 2
     ;; *SOFTWARE-VERSION* from the LISP package to the SYSTEM package.
    
    3 3
     (ext:without-package-locks
    
    4 4
         (unintern 'lisp::*software-version* "LISP"))
    
    5
    +
    
    6
    +#+(or random-mt19937 random-xoroshiro)
    
    7
    +(in-package "C")
    
    8
    +#+(or random-mt19937 random-xoroshiro)
    
    9
    +(deftransform random ((num &optional state)
    
    10
    +		      ((integer 1 #.(expt 2 32)) &optional *))
    
    11
    +  _N"use inline (unsigned-byte 32) operations"
    
    12
    +  (let* ((num-type (continuation-type num))
    
    13
    +	 (num-high (cond ((numeric-type-p num-type)
    
    14
    +			  (numeric-type-high num-type))
    
    15
    +			 ((union-type-p num-type)
    
    16
    +			  ;; Find the maximum of the union type.  We
    
    17
    +			  ;; know this works because if we're in this
    
    18
    +			  ;; routine, NUM must be a subtype of
    
    19
    +			  ;; (INTEGER 1 2^32), so each member of the
    
    20
    +			  ;; union must be a subtype too.
    
    21
    +			  (reduce #'max (union-type-types num-type)
    
    22
    +				  :key #'numeric-type-high))
    
    23
    +			 (t
    
    24
    +			  (give-up)))))
    
    25
    +    ;; Rather than doing (rem (random-chunk) num-high), we do,
    
    26
    +    ;; essentially, (rem (* num-high (random-chunk)) #x100000000).  I
    
    27
    +    ;; (rtoy) believe this approach doesn't have the bias issue with
    
    28
    +    ;; doing rem.  This method works by treating (random-chunk) as if
    
    29
    +    ;; it were a 32-bit fraction between 0 and 1, exclusive.  Multiply
    
    30
    +    ;; this by num-high to get a random number between 0 and num-high,
    
    31
    +    ;; This should have no bias.
    
    32
    +    (cond ((constant-continuation-p num)
    
    33
    +	   (if (= num-high (expt 2 32))
    
    34
    +	       '(random-chunk (or state *random-state*))
    
    35
    +	       '(values (bignum::%multiply 
    
    36
    +			 (random-chunk (or state *random-state*))
    
    37
    +			 num))))
    
    38
    +	  ((< num-high (expt 2 32))
    
    39
    +	   '(values (bignum::%multiply (random-chunk (or state *random-state*))
    
    40
    +		     num)))
    
    41
    +	  ((= num-high (expt 2 32))
    
    42
    +	   '(if (= num (expt 2 32))
    
    43
    +		(random-chunk (or state *random-state*))
    
    44
    +		(values (bignum::%multiply (random-chunk (or state *random-state*))
    
    45
    +					   num))))
    
    46
    +	  (t
    
    47
    +	   (error (intl:gettext "Shouldn't happen"))))))

  • src/code/rand-xoroshiro.lisp
    ... ... @@ -490,11 +490,8 @@
    490 490
       (declare (inline %random-single-float %random-double-float))
    
    491 491
       (cond
    
    492 492
         ((typep arg '(integer 1 #x100000000))
    
    493
    -     ;; Do the same thing as the deftransform would do.
    
    494
    -     (if (= arg (expt 2 32))
    
    495
    -	 (random-chunk state)
    
    496
    -	 (values (bignum::%multiply (random-chunk state)
    
    497
    -				    arg))))
    
    493
    +     ;; Let the compiler deftransform take care of this case.
    
    494
    +     (random arg state))
    
    498 495
         ((and (typep arg 'single-float) (> arg 0.0F0))
    
    499 496
          (%random-single-float arg state))
    
    500 497
         ((and (typep arg 'double-float) (> arg 0.0D0))