Random integer in VB.NET

2019-01-02 23:59发布

I need to generate a random integer between 1 and n (where n is a positive whole number) to use for a unit test. I don't need something overly complicated to ensure true randomness - just an old-fashioned random number.

How would I do that?

标签: vb.net random
11条回答
再贱就再见
2楼-- · 2019-01-03 00:27

As has been pointed out many times, the suggestion to write code like this is problematic:

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

The reason is that the constructor for the Random class provides a default seed based on the system's clock. On most systems, this has limited granularity -- somewhere in the vicinity of 20 ms. So if you write the following code, you're going to get the same number a bunch of times in a row:

Dim randoms(1000) As Integer
For i As Integer = 0 to randoms.Length - 1
    randoms(i) = GetRandom(1, 100)
Next

The following code addresses this issue:

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

I threw together a simple program using both methods to generate 25 random integers between 1 and 100. Here's the output:

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
查看更多
一夜七次
3楼-- · 2019-01-03 00:37
Dim rnd As Random = New Random
rnd.Next(n)
查看更多
Emotional °昔
4楼-- · 2019-01-03 00:38

You should create a pseudo-random number generator only once:

Dim Generator As System.Random = New System.Random()

Then, if an integer suffices for your needs, you can use:

Public Function GetRandom(myGenerator As System.Random, ByVal Min As Integer, ByVal Max As Integer) As Integer
'min is inclusive, max is exclusive (dah!)
Return myGenerator.Next(Min, Max + 1)
End Function

as many times as you like. Using the wrapper function is justified only because the maximum value is exclusive - I know that the random numbers work this way but the definition of .Next is confusing.

Creating a generator every time you need a number is in my opinion wrong; the pseudo-random numbers do not work this way.

First, you get the problem with initialization which has been discussed in the other replies. If you initialize once, you do not have this problem.

Second, I am not at all certain that you get a valid sequence of random numbers; rather, you get a collection of the first number of multiple different sequences which are seeded automatically based on computer time. I am not certain that these numbers will pass the tests that confirm the randomness of the sequence.

查看更多
聊天终结者
5楼-- · 2019-01-03 00:39

If you are using Joseph's answer which is a great answer, and you run these back to back like this:

dim i = GetRandom(1, 1715)
dim o = GetRandom(1, 1715)

Then the result could come back the same over and over because it processes the call so quickly. This may not have been an issue in '08, but since the processors are much faster today, the function doesn't allow the system clock enough time to change prior to making the second call.

Since the System.Random() function is based on the system clock, we need to allow enough time for it to change prior to the next call. One way of accomplishing this is to pause the current thread for 1 millisecond. See example below:

Public Function GetRandom(ByVal min as Integer, ByVal max as Integer) as Integer
    Static staticRandomGenerator As New System.Random
    max += 1
    Return staticRandomGenerator.Next(If(min > max, max, min), If(min > max, min, max))
End Function
查看更多
贪生不怕死
6楼-- · 2019-01-03 00:40

Microsoft Example Rnd Function

https://msdn.microsoft.com/en-us/library/f7s023d2%28v=vs.90%29.aspx

1- Initialize the random-number generator.

Randomize()

2 - Generate random value between 1 and 6.

Dim value As Integer = CInt(Int((6 * Rnd()) + 1))
查看更多
登录 后发表回答