2013-02-18 65 views
3

我需要一个方法,它返回从最小值到最大值的随机数,包括两个数字在内。我发现从斯蒂芬Toub和Shawn Farkas的,文章.NET Matters: Tales from the CryptoRandom在一些代码中的方法将是这个样子:RNGCryptoServiceProvider同时包含最小值和最大值

// Note - maxValue is excluded! 
public static int GetRandomIntBetween(int minValue, int maxValue) 
{ 
    if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue"); 
    if (minValue == maxValue) return minValue; 

    var rng = new RNGCryptoServiceProvider(); 
    var uint32Buffer = new byte[4]; 
    long diff = maxValue - minValue; 

    while (true) 
    { 
     rng.GetBytes(uint32Buffer); 
     uint rand = BitConverter.ToUInt32(uint32Buffer, 0); 
     const long max = (1 + (long)int.MaxValue); 
     long remainder = max % diff; 
     if (rand < max - remainder) 
     { 
      return (int)(minValue + (rand % diff)); 
     } 
    } 
} 

我试图使包括maxValue包括:

public static int GetRandomIntBetween(int minValue, int maxValue) 
{ 
    if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue"); 
    if (minValue == maxValue) return minValue; 

    // Make maxValue inclusive. 
    maxValue++; 

    var rng = new RNGCryptoServiceProvider(); 
    var uint32Buffer = new byte[4]; 
    long diff = maxValue - minValue; 

    while (true) 
    { 
     rng.GetBytes(uint32Buffer); 
     uint rand = BitConverter.ToUInt32(uint32Buffer, 0); 
     const long max = (1 + (long)int.MaxValue); 
     long remainder = max % diff; 
     if (rand < max - remainder) 
     { 
      return (int)(minValue + (rand % diff)); 
     } 
    } 
} 

看起来很奇怪,但似乎我可以保留前两个检查,即使语义略有不同,它仍然可以工作。结果数据看起来也不错。我错过了什么,或者我的更改是否正常?

PS - 我在问这个问题,因为生成随机数显然是一个非常微妙的问题,并且希望确定我的方法是正确的。

回答

1

您的更改是正确的,在[a,b]之间的随机整数是[a,b+1[之间的随机整数。

只要包括maxValue不是int.MaxValue,然后++会溢出,所以这将是更安全的不改变包括maxValue和移动变化差异的计算:

long diff = (long)maxValue - minValue + 1; 

然而,第二检查原函数显然是错误的,如果minValue == maxValue,返回的minValue不是minValue和maxValue之间的唯一值。

0

Look at my solution (click there)

您可以添加额外的方法到类:

public int NextInclusive(int minValue, int maxValue) { 
     return Next(minValue, maxValue + 1); 
} 
相关问题