开发者

C#: Random.NextDouble and including borders of the custom interval

I've used that formula for gettting a random double in custom interval:

Random r = new Random();
double Upper = 3.7, Lower = 11.4, Result;    
Result = Lower + (r.NextDouble() * (Upper - Lower))
// Lower is the lower border of interval, Upper is the upper border of interval

But keep in mind what MSDN says about Ne开发者_JAVA技巧xtDouble method:

A double-precision floating point number greater than or equal to 0.0, and less than 1.0.

That means interval in my sample code would include 3.7, but we can never get 11.4, right? How can I include the upper border?

Lower + (r.NextDouble() * (Upper - Lower + double.Epsilon))

Can this formula help? Or there is another variant of getting random double numbers in [3.7 ; 11.4] (including both borders) ?


Do you really need the upper interval for the double case? The odds of hitting exactly that value are really, really small, and should be statistically insignificant for almost all scenarios. If you're interested in numbers with a certain number of decimal places, then you can use some rounding to achieve what you need.


Since your using doubles what kind of precision do you actually use? Rounding the numbers might be enough. Alternatively you can use your own scaling like this:

static void Main(string[] args)
{
    var r = new Random(3);

    for (int i = 0; i < 100; i++)
    {
        Console.WriteLine(r.NextDouble(0, 1, 100));
    }

    Console.ReadKey();
}

public static double NextDouble(this Random r
    , double lower
    , double upper
    , int scale = int.MaxValue - 1
    )
{
    var d = lower + ((r.Next(scale + 1)) * (upper - lower) / scale);
    return d;
}

That will give you the lower and upper inclusive range at the specified scale. I threw in a default value for scale which gives you the highest possible precision, using this method.


The precision itself is a problem here, since 3.7 neither 11.4 have a precise double representation.

I think that since you are using random double precision number, I don't think this imprecision is something to care about.


Add the following

Result = Math.Round(Result, 8)

and voila.

The number 8 is the decimal places it will round to. When the random number is within 8 decimal places of the upper bound (example: 11.3999999990) then the result will round to the bound (answer: 11.4000000000).

Of course the round occurs for all the numbers, so choose your precision carefully. It really depends on the application if 8 decimal places is good. Your limits are 1 to 15.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜