C#:Random.NextDouble,包括自定义间隔的边界

本文关键字:边界 自定义 包括 Random NextDouble | 更新日期: 2023-09-27 17:58:04

我在自定义区间中使用了这个公式来获取随机双精度:

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

但请记住MSDN对NextDDouble方法的描述:

大于或等于0.0且小于1.0的双精度浮点数。

这意味着我的示例代码中的间隔将包括3.7,但我们永远不会得到11.4,对吧?如何包含上边界?

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

这个公式有用吗?或者在[3.7;11.4]中还有另一种获得随机双数的变体(包括两个边界)?

C#:Random.NextDouble,包括自定义间隔的边界

您真的需要双格的上间隔吗?达到这个值的几率非常非常小,几乎在所有情况下都应该是统计上微不足道的。如果你对有一定小数位数的数字感兴趣,那么你可以使用一些舍入来达到你所需要的。

由于您的使用加倍,您实际使用的精度是多少?四舍五入可能就足够了。或者,你可以像这样使用自己的缩放:

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;
}

这将为您提供指定比例的包含下限和上限的范围。我输入了一个默认的scale值,使用这个方法可以获得尽可能高的精度。

这里的精度本身就是个问题,因为3.7和11.4都没有精确的二重表示。

我认为,既然你使用的是随机双精度数,我不认为这种不精确性值得关注。

添加以下

Result = Math.Round(Result, 8)

瞧。

数字8是它将四舍五入到的小数位数。当随机数在上限的小数位数8位以内(例如:11.3999999990)时,结果将四舍五入到上限(答案:11.4000000)。

当然,所有数字都会进行舍入,所以要仔细选择精度。如果小数点后8位是好的,这实际上取决于应用程序。你的限制是1到15。