当前位置:  开发笔记 > 编程语言 > 正文

VB.NET中的随机整数

如何解决《VB.NET中的随机整数》经验,为你挑选了4个好方法。

我需要生成1到n之间的随机整数(其中n是正整数),用于单元测试.我不需要过于复杂的东西来确保真正的随机性 - 只是一个老式的随机数.

我该怎么办?



1> Dan Tao..:

正如已经多次指出的那样,编写这样的代码的建议是有问题的:

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


如果你想要一个bug,那么使用这个代码.MS使他们的Next()方法相当奇怪.Min参数是人们所期望的包容性最小值,但Max参数是人们不期望的唯一最小值.换句话说,如果你传递min = 1和max = 5,那么你的随机数将是1,2,3或4中的任何一个,但它永远不会包括5.
@ShawnKovac:我很欣赏它可能会令人惊讶.但在我看来,把它称为"越野车"有点矫枉过正; 它只是不是你期望的行为*.事实上,大多数随机数实现(我所知道的)都是这样工作的:包含下限,独占上限.在很多常见的用例中都很方便,例如从数组中选择一个随机项(在那里选择`0`和`array.length`之间的项).

2> Kibbee..:

要获得1到N(包括)之间的随机整数值,您可以使用以下内容.

CInt(Math.Ceiling(Rnd() * n)) + 1


*"在1和N之间(包括)"*错误,将返回"0"和"N"之间的值.`Math.Ceiling(0)`是'0`.
Rnd()可以返回0.如果发生这种情况,那么即使n> 0,结果也是0.因此,这会产生一个非常讨厌的错误,特别是因为它是如此罕见.如果你想要错误的代码,那么使用它.MS文档读取:"Rnd函数返回的值小于1,但大于或等于零." http://msdn.microsoft.com/en-us/library/f7s023d2(v=vs.90).aspx
当使用n = 11时,按原样尝试并运行到12的实例.不包容.MSDN有更好的例子:randomValue = CInt(Math.Floor((upperbound - lowerbound + 1)*Rnd()))+ lowerbound

3> Joseph Sturt..:

使用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)


返回New Random()看起来更简单.Next(minValue,maxValue)
真正.但是,如果用户想要一系列随机数(而不仅仅是一个),他们会希望保留随机引用.

4> Shawn Kovac..:

到目前为止,所有的答案都有问题或错误(复数,而不仅仅是一个).我会解释.但首先我要赞美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行代码就没有赢得最简单的奖项.但它也不是很复杂.)

''' 
''' Generates a random Integer with any (inclusive) minimum or (inclusive) maximum values, with full range of Int32 values.
''' 
''' Inclusive Minimum value. Lowest possible return value.
''' Inclusive Maximum value. Highest possible return value.
''' 
''' 
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

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有