I'm trying to generate random numbers from 0 to 1, including the borders 0 and 1 in Racket. Until now I didn't find a solution. Is there a nice way ?
-
2This question is unclear. What do you mean by "including the borders"? If you are simulating a uniform random variable on [0,1] then the probability of getting either 0 or 1 is vanishingly small. Just use the standard library RNG. – John Coleman Aug 23 '18 at 13:49
-
Think usually random number are float values and generated between zero and one (`0
– U880D Aug 23 '18 at 13:59 -
1With what probability should `0` and `1` appear? If the answer is anything other than `0`, you are no longer talking about a uniform random number on [0,1], hence the question is unclear since the desired distribution hasn't been specified. On the other hand, if the answer is `0`, then the standard `random` is sufficient. If my understanding of your question is incocrrect, please clarify, – John Coleman Aug 23 '18 at 14:15
-
It's exactly how @U880D pointed out. The usual random procedure, just returns a value x, where 0
– Newbie1234567 Aug 23 '18 at 15:27 -
"every value x should have the same probability" under-specifies a continuous distribution. If `X` is a continuous random variable on `[0,1]` then for any specific `x` in `[0,1]`, we have `Pr(X = x) = 0`. You never answered the question: with what probability do you want `0` and `1` to appear? – John Coleman Aug 23 '18 at 15:51
2 Answers
As soegaard mentions in his answer, you should just use (random)
. It is true that it produces a number in the open range (0, 1), not the closed range [0, 1] that you want. However, I’m going to present an argument backed by some numbers that the difference is irrelevant.
The random
procedure produces an IEEE 754 double-precision floating point number. The next-largest number representable by that format after 0 is approximately 4.94 × 10-324. If we assume that (random)
does, indeed, produce a number uniformly distributed over the range, then that would imply that the probability of ever actually producing 0.0
is one in 4.94 × 10324! To give you a little bit of context for that number, that means that even if you generated one billion random numbers every second, it would still take on average 6.41 × 10306 years to generate 0.0
even once.
The situation is a little less grim at the other end of the range, since the difference between 1 and the next-smallest number representable by double flonums is significantly larger: approximately 1.11 × 10-16. On this end of the range, if we once again generated one billion random numbers every second, then it would take on average “only” 104 days before generating 1.0
for the first time. However, this would still be completely insignificant compared to the enormous amount of data you had already generated (and indeed, it’s rather unlikely you are going to be generating a billion random numbers per second to begin with, since it takes well over a minute just to generate a billion random numbers on my machine).
Don’t worry about those missing ends of the range, since they really won’t matter. Just call (random)
and be done with it.

- 43,109
- 15
- 131
- 205
-
1This argument seems not completely convincing. The documentation suggests that the underlying RNG has a 52-bit internal state. `(random)` maps that to `(0,1)` but you could clearly map that state to `[0,1]` in such a way that `0` and `1` can occur. If so, it seems that the probability of getting `0` and `1` would then be at least `2^-52`, which is of course too small to worry about, but not quite as rare as your argument suggests. Still (+1) for showing OP that they are worried about something which is essentially nothing. – John Coleman Aug 23 '18 at 18:21
-
@JohnColeman I agree with you… I considered trying to incorporate information into this answer about the practical limits introduced by the implementation details of Racket’s PRNG, but I ended up not doing that. I think providing really precise numbers would involve looking into the way the PRNG works internally, which I don’t want to do. I thought about adding a throwaway line somewhere about upper/lower bounds due to the state size, and maybe I still should, but I don’t think it dramatically changes the takeaway from this answer. – Alexis King Aug 23 '18 at 18:26
-
In many ways, the numbers themselves don't really matter. It is an unavoidable *defect* of `(random)` that there are specific number which occur with non-zero probability. There is no plausible reason I can see for insisting that `0` and `1` join the list of numbers where this defect occurs. – John Coleman Aug 23 '18 at 18:31
-
@JohnColeman That’s true, though I think that interpretation is maybe not the most useful framing. I think a more motivating framing is that it is a defect of `(random)` that some numbers in the range will truly never be generated, rather than [almost never](https://en.wikipedia.org/wiki/Almost_surely). The fact that 0 and 1 belong to the set of numbers that will truly never be generated is less meaningful when you consider all the other numbers in the range [0, 1] that also belong to that set. – Alexis King Aug 23 '18 at 18:35
Use (random)
to generate a number between 0.0 and 1.0.
To include 0.0 and 1.0 you can use:
(define (r)
(/ (random 4294967087)
4294967086.0))

- 30,661
- 4
- 57
- 106
-
1random returns a real value between 0 and 1, without 0 and 1. My question was: How to create a function returning a random real number x, where 0<=x <=1. Sorry for being unprecise. – Newbie1234567 Aug 23 '18 at 15:31