我需要生成1到n之间的随机整数(其中n是正整数),用于单元测试.我不需要过于复杂的东西来确保真正的随机性 - 只是一个老式的随机数.
我该怎么办?
正如已经多次指出的那样,编写这样的代码的建议是有问题的:
Public Function GetRandom(ByVal Min As Integer, ByVal Max As Integer) As Integer Dim Generator As System.Random = New System.Random() Return Generator.Next(Min, Max) End Function
原因是Random
类的构造函数根据系统的时钟提供默认种子.在大多数系统中,这具有有限的粒度 - 在20毫秒附近.因此,如果您编写以下代码,您将连续多次获得相同的数字:
Dim randoms(1000) As Integer For i As Integer = 0 to randoms.Length - 1 randoms(i) = GetRandom(1, 100) Next
以下代码解决了此问题:
Public Function GetRandom(ByVal Min As Integer, ByVal Max As Integer) As Integer ' by making Generator static, we preserve the same instance ' ' (i.e., do not create new instances with the same seed over and over) ' ' between calls ' Static Generator As System.Random = New System.Random() Return Generator.Next(Min, Max) End Function
我使用两种方法将一个简单的程序汇总在一起,生成25个1到100之间的随机整数.这是输出:
Non-static: 70 Static: 70 Non-static: 70 Static: 46 Non-static: 70 Static: 58 Non-static: 70 Static: 19 Non-static: 70 Static: 79 Non-static: 70 Static: 24 Non-static: 70 Static: 14 Non-static: 70 Static: 46 Non-static: 70 Static: 82 Non-static: 70 Static: 31 Non-static: 70 Static: 25 Non-static: 70 Static: 8 Non-static: 70 Static: 76 Non-static: 70 Static: 74 Non-static: 70 Static: 84 Non-static: 70 Static: 39 Non-static: 70 Static: 30 Non-static: 70 Static: 55 Non-static: 70 Static: 49 Non-static: 70 Static: 21 Non-static: 70 Static: 99 Non-static: 70 Static: 15 Non-static: 70 Static: 83 Non-static: 70 Static: 26 Non-static: 70 Static: 16 Non-static: 70 Static: 75
要获得1到N(包括)之间的随机整数值,您可以使用以下内容.
CInt(Math.Ceiling(Rnd() * n)) + 1
使用System.Random:
Dim MyMin As Integer = 1, MyMax As Integer = 5, My1stRandomNumber As Integer, My2ndRandomNumber As Integer ' Create a random number generator Dim Generator As System.Random = New System.Random() ' Get a random number >= MyMin and <= MyMax My1stRandomNumber = Generator.Next(MyMin, MyMax + 1) ' Note: Next function returns numbers _less than_ max, so pass in max + 1 to include max as a possible value ' Get another random number (don't create a new generator, use the same one) My2ndRandomNumber = Generator.Next(MyMin, MyMax + 1)
到目前为止,所有的答案都有问题或错误(复数,而不仅仅是一个).我会解释.但首先我要赞美Dan Tao的见解,使用静态变量来记住Generator变量,因此多次调用它不会重复相同的#一遍又一遍,而且他给出了一个非常好的解释.但正如我现在解释的那样,他的代码遭遇了与其他大多数人相同的缺陷.
MS使他们的Next()方法相当奇怪.Min参数是人们所期望的包容性最小值,但Max参数是人们不期望的唯一最大值.换句话说,如果你传递分钟= 1和max = 5那么你的随机数是任何的1,2,3或4,但它绝不会包括5这是所有代码的第一个两个潜在的bug使用Microsoft的Random.Next()方法.
对于一个简单的答案(但仍然有其他可能但罕见的问题),那么你需要使用:
Private Function GenRandomInt(min As Int32, max As Int32) As Int32 Static staticRandomGenerator As New System.Random Return staticRandomGenerator.Next(min, max + 1) End Function
(我喜欢使用Int32
而不是Integer
因为它更清楚地表明int的大小,加上它的类型更短,但适合自己.)
我发现这种方法有两个潜在的问题,但对于大多数用途来说它是合适的(并且是正确的).所以如果你想要一个简单的解决方案,我相信这是正确的.
我在这个函数中看到的唯一两个问题是:1:当Max = Int32.MaxValue时,添加1会产生数字溢出.虽然这很少见,但仍有可能.2:当min> max + 1.当min = 10且max = 5时,Next函数抛出错误.这可能是你想要的.但它可能也不是.或考虑当min = 5和max = 4.通过添加1,5传递给Next方法,但它不会抛出错误,当它确实是一个错误,但我测试的Microsoft .NET代码返回5.所以当max = min时,它确实不是'独占'最大值.但是当Random.Next()函数的max 您可能只想在min> max时简单地交换数字,这样就不会引发错误,但这完全取决于所需的内容.如果你想在无效值上出错,那么当我们的代码中微软的独占最大值(max + 1)等于最小值时,最好也抛出错误,在这种情况下MS不能出错. 处理max = Int32.MaxValue有点不方便的解决办法,但我希望发布一个处理这两种情况的彻底函数.如果你想要不同于我编码的行为,请适合自己.但请注意这两个问题. 快乐的编码! 编辑:所以我需要一个随机整数生成器,我决定将它编码为"正确".因此,如果有人想要完整的功能,这里有一个实际工作.(但它只用2行代码就没有赢得最简单的奖项.但它也不是很复杂.)'''