ccl icon indicating copy to clipboard operation
ccl copied to clipboard

RANDOM does not exclude upper bound when passed a float

Open sjl opened this issue 5 years ago • 1 comments

http://clhs.lisp.se/Body/f_random.htm says (emphasis mine):

random limit &optional random-state => random-number ... Returns a pseudo-random number that is a non-negative number less than limit and of the same type as limit.

However, when calling random with a float as the limit, CCL sometimes returns an equal float:

Clozure Common Lisp Version 1.12 (v1.12) LinuxX8664 
 
For more information about CCL, please see http://ccl.clozure.com. 
 
CCL is free software.  It is distributed under the terms of the Apache 
Licence, Version 2.0. 
 
[ClozureCL] COMMON-LISP-USER> (loop :repeat 1000000000 :do (assert (< (random 57.0) 57.0))) 
> Error: Failed assertion: (< (RANDOM 57.0) 57.0) 
> While executing: CCL::%ASSERTION-FAILURE, in process listener(1). 
> Type :GO to continue, :POP to abort, :R for a list of available restarts. 
> If continued: test the assertion again. 
> Type :? for other options. 
 
[1] > 

@phoe did some preliminary source diving to track this down: https://plaster.tymoon.eu/view/2030#2030

Unrelated to Lisp, https://experilous.com/1/blog/post/perfect-fast-random-floating-point-numbers is an interesting read for further information about making random floats that folks might find useful.

sjl avatar Aug 25 '20 22:08 sjl

In addition to my analysis from above, it seems that we can use https://github.com/Clozure/ccl/blob/275105afd94706d95ac955178316074931822c42/level-0/X86/x86-float.lisp#L26-L54 for low-level float creation.

This might be useful if we want to copy how SBCL does this: https://github.com/sbcl/sbcl/blob/7492ec61bd7db6da9f9cbb56cebf7f80a198c883/src/code/target-random.lisp#L317-L337

phoe avatar Aug 25 '20 22:08 phoe