ccl
ccl copied to clipboard
RANDOM does not exclude upper bound when passed a float
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.
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