Reputation: 560
I'm surprised I couldn't find an answer to this anywhere, so perhaps I'm missing something.
The NextDouble
method of the System.Random
class returns doubles within the range of [0.0,1.0)
. This is a half-open interval which returns 0.0 <= x < 1.0
.
I need a closed interval [0.0,1.0]
such that 0.0 <= x <= 1.0
. In C++, I could use std::nextafter
, which returns me the smallest representable floating point that is greater than the passed parameter (e.g. std::nextafter(1.0, 2.0)
would return 1.0000001192092895508
). I can't seem to find an equivalent in C#.
I'm working with tons of highly precise numbers (16bit), so although 1.0 may seldom appear, I still need it to have the ability to. And although the difference between 1.0
and 1.0000001192092895508
may seem negligible (and often is), the difference is one that will matter in this case.
After implementing a solution similar to this version of NextAfter
, I sometimes get numbers larger than the maximum (e.g. 5.00000027008353
for [0.0,5.0]
)
Random.NextDouble() * ((NextAfter(max, max + 1.0) - min) + min);
How can I generate random floating point numbers with a closed interval? I'm going to be executing this many times so preferably something that does not take too long to execute (like calling Random
multiple times or using while loops and rejection sampling). Also, it's necessary to be unbiased, yielding uniform results (i.e. no number should be more likely to appear than any other number).
Upvotes: 3
Views: 460
Reputation: 659964
This seems straightforward:
Now you've got a sequence of random numbers on the closed interval where 1.0 appears the expected number of times on average. You get one expensive bell-shaped computation every billion or so, which amortizes out to basically zero cost.
Upvotes: 2
Reputation: 1836
Your bit representation of floats implies a limited number of distinct values. Determine the number of possible float values, get a random int in that range and map/convert this value to your float range.
Upvotes: 0