C# 如何生成具有(单独)最小/最大限制的随机双精度?
这就是我想要实现的目标:C# 如何生成具有(单独)最小/最大限制的随机双精度?,c#,math,random,C#,Math,Random,这就是我想要实现的目标: public double NextMin (double min) { //Returns a double that is greater than or equal to "min". } public double NextMax (double max) { //Returns a double that is lesser than "max". } 我尝试了范围扩展,但由于溢出,它返回很多“无穷大”: // Range expandi
public double NextMin (double min)
{
//Returns a double that is greater than or equal to "min".
}
public double NextMax (double max)
{
//Returns a double that is lesser than "max".
}
我尝试了范围扩展,但由于溢出,它返回很多“无穷大”:
// Range expanding for min
random.NextDouble() * (double.MaxValue - min) + min;
// Range expanding for max
random.NextDouble() * (max - double.MinValue) + double.MinValue;
澄清:我需要返回范围尽可能大,这意味着它们应该同时包含负数和正数
private Random rng = new Random();
private double GetRandomDouble(double min, double max)
{
// Get the base value, scale first and then shift.
return rng.NextDouble()*(max - min) + min;
}
编辑:我有点困惑,为什么这对我有效而对别人无效。我刚刚运行的代码是VS 2015.3,三次运行中没有一次检测到无限值:
class Program
{
static void Main(string[] args)
{
const int maxIterations = 100000;
var infinityDetected = false;
for (int i = 0; i < maxIterations; i++)
{
var d = GetRandomDouble(double.MinValue, double.MaxValue);
if (double.IsInfinity(d))
{
infinityDetected = true;
Console.WriteLine("Infinity detected");
break;
}
Console.WriteLine(d);
}
if (!infinityDetected)
{
for (int i = 0; i < maxIterations; i++)
{
var d = GetRandomDouble(-1.0, double.MaxValue);
if (double.IsInfinity(d))
{
infinityDetected = true;
Console.WriteLine("Infinity detected");
break;
}
Console.WriteLine(d);
}
}
if (!infinityDetected)
{
for (int i = 0; i < maxIterations; i++)
{
var d = GetRandomDouble(double.MinValue, 1.0);
if (double.IsInfinity(d))
{
Console.WriteLine("Infinity detected");
break;
}
Console.WriteLine(d);
}
}
Console.ReadLine();
}
private static Random rng = new Random();
private static double GetRandomDouble(double min, double max)
{
// Get the base value, scale first and then shift.
return rng.NextDouble() * (max - min) + min;
}
}
类程序
{
静态void Main(字符串[]参数)
{
常量int最大迭代次数=100000;
var infinityDetected=false;
对于(int i=0;i
试试这个:
random.NextDouble() * (double.MaxValue - min) + min;
random.NextDouble() * (double.MinValue + max) - max;
这应该可以更好地处理溢出
// Range expanding for min
double.MaxValue - random.NextDouble() * (double.MaxValue - min);
// Range expanding for max
double.MinValue + random.NextDouble() * (max - double.MinValue);
第二个与您发布的相同,我不明白为什么这个不起作用。我相信这适用于一般情况(前提是
min
小于max
)
调用Console.WriteLine(getrandouble(double.MinValue,double.MaxValue))
然后正确地生成介于double.MinValue
和double.MaxValue
之间的值
然后你只需将你想要的两种方法具体化,如下所示:
public double NextMin(double min)
{
return GetRandomDouble(min, double.MaxValue);
}
public double NextMax(double max)
{
return GetRandomDouble(double.MinValue, max);
}
你为什么要这样做?这是X-Y问题吗?@Enigmativity我将生成一个程序宇宙,我需要一些随机向量采样。在我的算法中需要这些方法。如果假设
double.MaxValue==10.0
和double.MinValue==-10.0
,请看这里,然后double.MaxValue-double.MinValue==20.0
,但这大于double
的允许范围(在此假设下)。因此,您会遇到无穷大问题。第一个块返回所有无穷大。@S.Tarıkıetin虽然不输出无穷大。我只是运行了一个循环,调用了getrandouble(double.MinValue,double.MaxValue)
100000次,在传递结果时没有一次调用double.IsInfinity
returntrue
。也就是说,输出看起来不像是随机排列,所以有点不对劲。@jmcillhinney-我刚刚运行了这段代码,得到了∞代码>。OP是对的。@Enigmativity,OP可能是对的,他们得到了无穷大,但我运行了它,我没有,所以我不确定有什么不同。正如我所说,我运行了一个循环,使用double
的限制执行了该方法100000次,没有任何问题。根据您对分销的评论,我现在意识到我看到的输出是完全合适的。因此,我的代码似乎对我来说100%有效,但对其他人来说显然不行。我真的不知道为什么会这样。确实如此。但是我在(double.MinValue,double.MaxValue)
范围内生成了10000个随机数,它们的指数都是308、307或306。指数有什么问题?@S.Tarıkıetin-指数没有问题。这在数学上是正确的。0.0
和1.0
之间90%的随机数大于0.1
和0.1*double。MaxValue
是1.79769313486232E+307
,所以你应该预计0.0
和double.MaxValue
之间90%的随机数大于1.79769313486232E+307
。因此这是其中之一那些数学毫无意义的时刻。。。我想分别选择尾数和指数是解决这种情况的方法。@S.Tarıkıetin-那么你就没有一个统一的分布了。如果你想要一个均匀的分布,那么你就坚持这个答案。否则你会得到某种非均匀分布,比如钟形曲线。我认为这种情况下,数学是有意义的,但它不是直观的,因为我们的大脑无法处理308位的数字。@s.Tarıkıetin正如你所要求的,数学给出了给定范围内均匀分布的随机值。也许你有不同的想法,但这不是数学的错。如果第一种方法中的min
小于0.0
,第二种方法中的max
大于0.0
,则会失败。当然,这两种方法都是正确的。现在要想知道如何在不损失1-2位精度的情况下实现这一点已经太迟了+我认为你无法避免。如果计算是double.MaxValue-
double.MinValue`则必须除以2.0
,使结果回到双精度内
public double NextMin(double min)
{
return GetRandomDouble(min, double.MaxValue);
}
public double NextMax(double max)
{
return GetRandomDouble(double.MinValue, max);
}