【问题标题】:Create random double, unified over whole range of valid doubles创建随机双精度,在整个有效双精度范围内统一
【发布时间】:2017-11-19 17:04:34
【问题描述】:

Best way to generate a random float in C# 表示浮点数,Generating a Random Decimal in C# 表示十进制数,但是,没有问题的 double 还涵盖了“double 的全部范围”。

如何正确生成在所有有效(即非 NaN/无限/...)值上均匀分布的随机双精度值?

【问题讨论】:

  • 均匀分布是什么意思?您希望每个双精度数均等,还是希望数学上均匀分布(即,在区间 [x, y] 中获得数字的机会与 (y-x) 成正比)?
  • 不清楚你在问什么。调用random.NextDouble() 然后将其缩放到[double.MinValue, double.MaxValue] 范围内如何不能满足您的需求?为什么不直接应用你找到的float 的答案,而是使用double 类型呢?你尝试过任何东西吗?
  • ad float) 我不确定如何应用 double 的答案,因为没有人描述常量的来源 (*2.0, -1.0, -126, +128)
  • 广告缩放)怎么做?如果 r.nextDouble() 非常高,旧的 rangeMin + (rangeMax - rangeMin) * r.nextDouble() 将无法工作,因为它会发生溢出。
  • 广告分布)我希望它具有与 nextDouble() 相同的分布。

标签: c# random double


【解决方案1】:

您的缩放不起作用,因为缩放因子实际上会大于不起作用的 double.MaxValue。

var number = r.NextDouble() * 2d - 1d; // r in [-1, 1]
return number * double.MaxValue;

这段代码sn-p首先在[-1,1]范围内生成一个均匀分布的随机数。 比它转换成你想要的范围。

这仅在两个范围相等时才有效,这适用于您的用例 (double.MaxValue == Math.Abs(double.MinValue))

注意:根据https://docs.microsoft.com/en-us/dotnet/api/system.random.nextdouble?view=netframework-4.7,Random.NextDouble()的上限实际上是0.99999999999999978)

根据您的问题,如何获得包含 1 的范围,您可以自行实现 random.NextDouble() 方法。 参考实现 (http://referencesource.microsoft.com/#mscorlib/system/random.cs,bb77e610694e64ca) 使用 Random.Next() 方法并将其映射到双精度,其中Random.Next() 方法的范围为[0, Int32.MaxValue - 1]。所以只需使用r.Next() * (1.0 / (Int32.MaxValue - 1)),它将返回[0, 1] 范围内的双精度值。

顺便说一句,我认为文档不正确,因为Random.NextDouble() 可以生成的最大值是0.999999999534339,即(Int32.MaxValue - 1) * (1.0 / Int32.MaxValue) 而不是0.99999999999999978

【讨论】:

  • 听起来不错 - 我只是有点担心 1 不在范围内。所以算法永远不会输出double.MaxValue 作为结果。您是否认为可以将2d 因子更改为稍大一点的值,以便 1 也包含在范围内?
猜你喜欢
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
相关资源
最近更新 更多