Dan*_*Tao 70
正如已经多次指出的那样,编写这样的代码的建议是有问题的:
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
Run Code Online (Sandbox Code Playgroud)
原因是Random类的构造函数根据系统的时钟提供默认种子.在大多数系统中,这具有有限的粒度 - 在20毫秒附近.因此,如果您编写以下代码,您将连续多次获得相同的数字:
Dim randoms(1000) As Integer
For i As Integer = 0 to randoms.Length - 1
randoms(i) = GetRandom(1, 100)
Next
Run Code Online (Sandbox Code Playgroud)
以下代码解决了此问题:
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
Run Code Online (Sandbox Code Playgroud)
我使用两种方法将一个简单的程序汇总在一起,生成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
Run Code Online (Sandbox Code Playgroud)
Kib*_*bee 56
要获得1到N(包括)之间的随机整数值,您可以使用以下内容.
CInt(Math.Ceiling(Rnd() * n)) + 1
Run Code Online (Sandbox Code Playgroud)
Jos*_*ant 33
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)
Run Code Online (Sandbox Code Playgroud)
到目前为止,所有的答案都有问题或错误(复数,而不仅仅是一个).我会解释.但首先我要赞美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
Run Code Online (Sandbox Code Playgroud)
(我喜欢使用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时,它会抛出ArgumentOutOfRangeException.因此,微软的实施在这方面确实存在不一致和错误.
您可能只想在min> max时简单地交换数字,这样就不会引发错误,但这完全取决于所需的内容.如果你想在无效值上出错,那么当我们的代码中微软的独占最大值(max + 1)等于最小值时,最好也抛出错误,在这种情况下MS不能出错.
处理max = Int32.MaxValue有点不方便的解决办法,但我希望发布一个处理这两种情况的彻底函数.如果你想要不同于我编码的行为,请适合自己.但请注意这两个问题.
快乐的编码!
编辑:所以我需要一个随机整数生成器,我决定将它编码为"正确".因此,如果有人想要完整的功能,这里有一个实际工作.(但它只用2行代码就没有赢得最简单的奖项.但它也不是很复杂.)
''' <summary>
''' Generates a random Integer with any (inclusive) minimum or (inclusive) maximum values, with full range of Int32 values.
''' </summary>
''' <param name="inMin">Inclusive Minimum value. Lowest possible return value.</param>
''' <param name="inMax">Inclusive Maximum value. Highest possible return value.</param>
''' <returns></returns>
''' <remarks></remarks>
Private Function GenRandomInt(inMin As Int32, inMax As Int32) As Int32
Static staticRandomGenerator As New System.Random
If inMin > inMax Then Dim t = inMin : inMin = inMax : inMax = t
If inMax < Int32.MaxValue Then Return staticRandomGenerator.Next(inMin, inMax + 1)
' now max = Int32.MaxValue, so we need to work around Microsoft's quirk of an exclusive max parameter.
If inMin > Int32.MinValue Then Return staticRandomGenerator.Next(inMin - 1, inMax) + 1 ' okay, this was the easy one.
' now min and max give full range of integer, but Random.Next() does not give us an option for the full range of integer.
' so we need to use Random.NextBytes() to give us 4 random bytes, then convert that to our random int.
Dim bytes(3) As Byte ' 4 bytes, 0 to 3
staticRandomGenerator.NextBytes(bytes) ' 4 random bytes
Return BitConverter.ToInt32(bytes, 0) ' return bytes converted to a random Int32
End Function
Run Code Online (Sandbox Code Playgroud)
小智 5
Microsoft Rnd 函数示例
https://msdn.microsoft.com/en-us/library/f7s023d2%28v=vs.90%29.aspx
1- 初始化随机数生成器。
Randomize()
Run Code Online (Sandbox Code Playgroud)
2 - 生成 1 到 6 之间的随机值。
Dim value As Integer = CInt(Int((6 * Rnd()) + 1))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
299629 次 |
| 最近记录: |