2016-08-04 61 views
2

這就是我想要達到的目標:如何用(單獨)最小/最大限制生成一個隨機double?

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; 

澄清:我需要的返回範圍儘可能大,這意味着它們應該同時包含底片和正片。

+1

爲什麼你要這麼做?這是X-Y問題嗎? – Enigmativity

+0

@Enigmativity我將生成一個程序性的宇宙,我需要一些隨機的矢量樣本。這些方法在我的算法中是需要的。 –

+0

看看這裏http://stackoverflow.com/questions/3365337/best-way-to-generate-a-random-float-in-c-sharp – Blorgbeard

回答

4

我相信這適用於一般情況(假設min小於max)。

private Random rng = new Random(); 

private double GetRandomDouble(double min, double max) 
{ 
    var half_min = min/2.0; 
    var half_max = max/2.0; 
    var average = half_min + half_max; 
    var factor = max - average; 

    return (2.0 * rng.NextDouble() - 1.0) * factor + average; 
} 

Console.WriteLine(GetRandomDouble(double.MinValue, double.MaxValue));調用然後正確double.MinValuedouble.MaxValue之間產生的值。

然後你只需充實你的願望兩種方法,就像這樣:

public double NextMin(double min) 
{ 
    return GetRandomDouble(min, double.MaxValue); 
} 

public double NextMax(double max) 
{ 
    return GetRandomDouble(double.MinValue, max); 
} 
+0

確實如此。但是,我在'(double.MinValue,double.MaxValue)'範圍內生成了10000個隨機數,它們的指數都是308,307或306.指數的問題是什麼? –

+3

@S.TarıkÇetin - 指數沒有問題。這在數學上是正確的。 '0.0'和'1.0'之間的隨機數的90%大於'0.1'和​​'0.1 * double.MaxValue'是'1.79769313486232E + 307',所以您應該期望90%的隨機數在'0.0'和'double .maxValue'大於'1.79769313486232E + 307'。 – Enigmativity

+0

所以這是數學沒有任何意義的時刻之一......我想單獨選擇尾數和指數是這種情況的方法。 –

-1
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; 
    } 
} 
+0

第一塊返回所有無限。 –

+0

@S.TarıkÇetin儘管[Ideone](http://ideone.com/RY1K7S)不輸出無窮大。 –

+1

我剛剛運行了一個循環,它調用了'GetRandomDouble(double.MinValue,double.MaxValue)'100,000次,而double.IsInfinity'在傳遞結果時不返回'true'。也就是說,輸出看起來不像一個隨機傳播,所以有些不對勁。 – jmcilhinney

-2

試試這個:

random.NextDouble() * (double.MaxValue - min) + min; 
random.NextDouble() * (double.MinValue + max) - max; 
-1

這應該與溢出打得更漂亮。

// Range expanding for min 
double.MaxValue - random.NextDouble() * (double.MaxValue - min); 

// Range expanding for max 
double.MinValue + random.NextDouble() * (max - double.MinValue); 

第二個實際上是一樣的,你貼一個,我不明白爲什麼一個不會奏效。

+1

這會失敗,第一種方法中'min'小於'0.0',第二種情況'max'大於'0.0'。兩者都會溢出。 – Enigmativity

+0

@Enigmativity當然是的。在這裏,要弄清楚它是如何完成的*沒有*在你的解決方案中失去了1-2位的精度。 +1。 – dxiv

+0

我不認爲你可以避免它。如果計算結果是double.MaxValue - double.MinValue,那麼你必須用'2.0'除以使結果適合'double'。你必須失去精確度。 – Enigmativity

相關問題