Random Integer in VB - NET - Stack Overflow
Random Integer in VB - NET - Stack Overflow
How are we doing? Please help us improve Stack Overflow. Take our short survey
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-
60 fashioned random number.
vb.net random
12
To get a random integer value between 1 and N (inclusive) you can use the following.
58 CInt(Math.Ceiling(Rnd() * n)) + 1
6 "between 1 and N (inclusive)" wrong, will return a value between 0 and N . Math.Ceiling(0) is 0 . –
Qtax Jul 18 '12 at 21:09
5 Rnd() can return 0. If this happens then even when n > 0, the result would be 0. Thus this would give a very
nasty bug especially because it is so rare. if you want buggy code, then use this. MS documentation reads:
"The Rnd function returns a value less than 1, but greater than or equal to zero." msdn.microsoft.com/en-
us/library/f7s023d2(v=vs.90).aspx – Shawn Kovac Jan 30 '14 at 15:10
5 Tried this out as is and ran into instance of 12 when using n=11. Not inclusive. MSDN has better example:
randomValue = CInt(Math.Floor((upperbound - lowerbound + 1) * Rnd())) + lowerbound – eric1825 Dec 19
'14 at 18:27
Rnd() is part of [0;1[. If you want a number part of ]0;1], then you can use 1-Rnd() . – Ama May 17 '19 at
17:31
By usingAs
ourhas
site,been
you acknowledge
pointed outthat
manyyoutimes,
have read and understand
the suggestion our Cookie
to write code Policy, Privacy
like this Policy, and
is problematic:
our Terms of Service.
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 1/11
5/6/2020 Random integer in VB.NET - Stack Overflow
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:
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
By using our site, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and
edited Apr 20 '10 at 19:03 answered Apr 20 '10 at 18:57
our Terms of Service.
Dan Tao
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 2/11
5/6/2020 Random integer in VB.NET - Stack Overflow
i think this will never actually generate "100". it's between min and less than MaxValue actually (I think) –
Max Hodges Apr 11 '12 at 13:29
1 @maxhodges: Yeah, I think you're right. There's an unfortunate ambiguity in the word "between"; I don't
know if the OP cares whether 100 is included or not. I didn't, personally; my answer was only intended to
illustrate sharing a Random object among multiple function calls using the Static keyword. – Dan Tao
Apr 11 '12 at 13:56
4 if you want a bug, then use this code. MS made their Next() method rather odd. the Min parameter is the
inclusive minimum as one would expect, but the Max parameter is the exclusive minimum as one would
NOT expect. in other words, if you pass min=1 and max=5 then your random numbers would be any of 1,
2, 3, or 4, but it would never include 5. – Shawn Kovac Jan 30 '14 at 15:24
3 @ShawnKovac: I can appreciate that it can be surprising. But calling it "buggy" is a little overkill, in my
opinion; it just wasn't the behavior you were expecting. The truth is that most random number
implementations (that I know of) work this way: inclusive lower bound, exclusive upper bound. It can be
convenient in a lot of common use cases, like selecting a random item from an array (where you select the
item between 0 and array.length ). – Dan Tao Jan 30 '14 at 15:37
1 thanks Dan. i appreciate that feedback. it is awkward at best, and then i see programmers who think
'minimum' and 'maximum' have a consistent similarity as being inclusive and exclusive... yes, as i would.
but this is human. so many 'quirks' in programming is why programming is as tricky as it is. and we just
need to write better code. i appreciate your feedback tho. thanks. – Shawn Kovac Jan 30 '14 at 16:37
Use System.Random:
' Get another random number (don't create a new generator, use the same one)
My2ndRandomNumber = Generator.Next(MyMin, MyMax + 1)
5 Looks simpler with return New Random().Next(minValue,maxValue) – Ignacio Soler Garcia Feb 2 '10 at
10:25
2 True. However, if the user wanted a sequence of random numbers (rather than just one), they would want
to hold onto the Random reference. – Joseph Sturtevant Feb 3 '10 at 0:01
1 Change Dim Generator to Static Generator and you've got an instance you can hold onto (not a
thread-safe one, but that's not going to matter in most realistic scenarios). – Dan Tao Apr 20 '10 at 18:50
By using1our itsite,
looks simpler,
you but this code
acknowledge is plain
that you havewrong. if you
read and want a bug,
understand ourthen use this
Cookie code.
Policy MS made
, Privacy their
Policy Next()
, and
method rather odd. the Min parameter is the inclusive minimum as one would expect, but the Max
our Terms of Service.
parameter is the exclusive minimum as one would NOT expect. in other words, if you pass min=1 and
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 3/11
5/6/2020 Random integer in VB.NET - Stack Overflow
max=5 then your random numbers would be any of 1, 2, 3, or 4, but it would never include 5. –
Shawn Kovac Jan 30 '14 at 15:15
@ShawnKovac - Good catch. I hadn't noticed the inclusive\exclusive mismatch between Random.Next's
min & max parameters. Code sample updated. – Joseph Sturtevant Feb 1 '14 at 19:27
All the answers so far have problems or bugs (plural, not just one). I will explain. But first I want to
compliment Dan Tao's insight to use a static variable to remember the Generator variable so
5 calling it multiple times will not repeat the same # over and over, plus he gave a very nice
explanation. But his code suffered the same flaw that most others have, as i explain now.
MS made their Next() method rather odd. the Min parameter is the inclusive minimum as one
would expect, but the Max parameter is the exclusive maximum as one would NOT expect. in
other words, if you pass min=1 and max=5 then your random numbers would be any of 1, 2, 3, or
4, but it would never include 5. This is the first of two potential bugs in all code that uses
Microsoft's Random.Next() method.
For a simple answer (but still with other possible but rare problems) then you'd need to use:
(I like to use Int32 rather than Integer because it makes it more clear how big the int is, plus it
is shorter to type, but suit yourself.)
I see two potential problems with this method, but it will be suitable (and correct) for most uses.
So if you want a simple solution, i believe this is correct.
The only 2 problems i see with this function is: 1: when Max = Int32.MaxValue so adding 1
creates a numeric overflow. altho, this would be rare, it is still a possibility. 2: when min > max + 1.
when min = 10 and max = 5 then the Next function throws an error. this may be what you want.
but it may not be either. or consider when min = 5 and max = 4. by adding 1, 5 is passed to the
Next method, but it does not throw an error, when it really is an error, but Microsoft .NET code
that i tested returns 5. so it really is not an 'exclusive' max when the max = the min. but when max
< min for the Random.Next() function, then it throws an ArgumentOutOfRangeException. so
Microsoft's implementation is really inconsistent and buggy too in this regard.
you may want to simply swap the numbers when min > max so no error is thrown, but it totally
depends on what is desired. if you want an error on invalid values, then it is probably better to
also throw the error when Microsoft's exclusive maximum (max + 1) in our code equals minimum,
where MS fails to error in this case.
handling a work-around for when max = Int32.MaxValue is a little inconvenient, but i expect to
post a thorough function which handles both these situations. and if you want different behavior
than how i coded it, suit yourself. but be aware of these 2 issues.
Happy coding!
By usingEdit: So you
our site, i needed a random
acknowledge that integer
you havegenerator, and i decided
read and understand to code
our Cookie it 'right'.
Policy So Policy
, Privacy if anyone
, and wants
the
our Terms of full functionality,
Service. here's one that actually works. (But it doesn't win the simplest prize with only
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 4/11
5/6/2020 Random integer in VB.NET - Stack Overflow
''' <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
1 Complete nonsense. As Bill said, the behaviour of Next() is entirely normal, not "rather odd". –
Lightness Races in Orbit Sep 17 '15 at 14:39
1 To be fair, as "normal" as it might be for built-in functions of various programming languages, it's actually
rather odd for the rest of the world. When's the last time you heard someone say 1D6 gives you a number
between 1 and 7? For anyone who hasn't carefully read the language's documentation and isn't particularly
familiar with the normally odd behavior of RNG functions, they could be in for a surprise and not really know
what happened. – MichaelS Dec 28 '15 at 7:22
@MichaelS, you lost me with '1D6' giving a # between 1 & 7. i don't understand your 'D'. But also in
regards 2 how Microsoft's Random.Next(min, max) works, the program provides 1 & 7 and the method
returns a # within the range of 1 & 6. So i think u were slightly off of the exact accuracy of your analogy
(unless you were referring to some other nonsensical behavior. But if you were intending to refer to
Microsoft's, i just say that your little mix-up is perfectly normal because what MS did makes no logical
sense (other than what others have pointed out: that it's become the new 'norm'). – Shawn Kovac Dec 29
'15 at 13:09
And i am simply vocalizing a little bit of logic that it is better logically to use inclusive min and inclusive max
for consistency and to reject the quasi-'norm' that has began. That's all. :) – Shawn Kovac Dec 29 '15 at
13:11
1D6 means roll one six-sided die -- the kind used in many board games or a tabletop RPG. The numbers
range from 1 to 6, inclusive, and people would say "1 to 6", not "1 to 7" and assume you know 7 isn't
included. You could use similar analogies from many other aspects of life. If I say a baseball league is for
children between 12 and 14, I'm including both 12 and 14. Etc. I can't think of a practical example of
excluding the upper bound of a range outside a math class. – MichaelS Jan 4 '16 at 4:57
By using our site, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and
our Terms of Service.
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 5/11
5/6/2020 Random integer in VB.NET - Stack Overflow
2 if you want bugs, then use this code. MS made their Next() method rather odd. the Min parameter is the
inclusive minimum as one would expect, but the Max parameter is the exclusive maximum as one would
NOT expect. in other words, if you pass min=1 and max=5 then your random numbers would be any of 1,
2, 3, or 4, but it would never include 5. – Shawn Kovac Jan 30 '14 at 16:31
5 @ShawnKovac That's how most random number generators are implemented. – Bill the Lizard Jan 30 '14
at 17:53
https://msdn.microsoft.com/en-us/library/f7s023d2%28v=vs.90%29.aspx
3
1- Initialize the random-number generator.
Randomize()
By usingas
ourmany times
site, you as you like.
acknowledge thatUsing the read
you have wrapper function isour
and understand justified
Cookieonly because
Policy, Privacythe maximum
Policy, and
value
our Terms is exclusive
of Service. - I know that the random numbers work this way but the definition of .Next is
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 6/11
5/6/2020 Random integer in VB.NET - Stack Overflow
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.
If you are using Joseph's answer which is a great answer, and you run these back to back like
this:
1
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:
2 if you want a bug, then use this code. MS made their Next() method rather odd. the Min parameter is the
inclusive minimum as one would expect, but the Max parameter is the exclusive minimum as one would
NOT expect. in other words, if you pass min=1 and max=5 then your random numbers would be any of 1,
2, 3, or 4, but it would never include 5. – Shawn Kovac Jan 30 '14 at 15:26
@ShawnKovac Thank you for enlightening me about the .Next function not returning the Max number and
the use of the static system.random object (although the name Min and Max are probably no longer
By using our appropriate since this is that
site, you acknowledge nowyou
just have
a range:
readA and
to B). I did a test,our
understand and the performance
Cookie of thePolicy
Policy, Privacy two are equal.
, and
Also, I use integer instead of int32 because it is currently bound to int32 (making them almost the same)
our Terms of Service.
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 7/11
5/6/2020 Random integer in VB.NET - Stack Overflow
and since I do a lot of work in SQL, I like the syntax and don't mind typing the 'e' before my 'tab.' (To each
their own though.) ~Cheers – Rogala Mar 21 '14 at 19:16
thanks for caring to correct your code. you are well beyond many other people in that. Yes, Int32 and
Integer produces the same effect, as far as i know, exactly the same. Except to me, Int32 is more clear, for
people who don't know what size of Integer an 'Ingeger' is. That's the biggest reason i use Int32. But i
understand it's totally a preference thing. – Shawn Kovac Mar 27 '14 at 16:06
I also like the shorter Int32 alias, and yes, with intellisence the typing is about equal. But i like more
compact reading too. But when i code C#, i still like to use the more specific Int32 rather than its even
shorter 'int' in case newbies are looking at my code, for other people's clarity sake. But to each his own. :) –
Shawn Kovac Mar 27 '14 at 16:08
I just want to point out that your code will either bug out or throw an error if your max = Integer.MaxValue.
Of course, this usually won't matter, but if you wanted to eliminate that potential issue, you can see my
answer where i provided a solution to give the full range of random Int, if the user wanted to include
Integer.MaxValue. Unfortunately, Microsoft just didn't make it easy to have very robust code for this when
they implemented what i call an extremely quirky random function. Truly robust code is hard to come by. :(
– Shawn Kovac Mar 27 '14 at 16:11
Just for reference, VB NET Fuction definition for RND and RANDOMIZE (which should give the
same results of BASIC (1980 years) and all versions after is:
0
Public NotInheritable Class VBMath
' Methods
Private Shared Function GetTimer() As Single
Dim now As DateTime = DateTime.Now
Return CSng((((((60 * now.Hour) + now.Minute) * 60) + now.Second) +
(CDbl(now.Millisecond) / 1000)))
End Function
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 8/11
5/6/2020 Random integer in VB.NET - Stack Overflow
End If
num2 = (((num2 And &HFFFF) Xor (num2 >> &H10)) << 8)
rndSeed = ((rndSeed And -16776961) Or num2)
projectData.m_rndSeed = rndSeed
End Sub
End Class
<__DynamicallyInvokable> _
Public Sub New(ByVal Seed As Integer)
Me.SeedArray = New Integer(&H38 - 1) {}
Dim num4 As Integer = If((Seed = -2147483648), &H7FFFFFFF, Math.Abs(Seed))
Dim num2 As Integer = (&H9A4EC86 - num4)
Me.SeedArray(&H37) = num2
Dim num3 As Integer = 1
Dim i As Integer
For i = 1 To &H37 - 1
Dim index As Integer = ((&H15 * i) Mod &H37)
Me.SeedArray(index) = num3
num3 = (num2 - num3)
If (num3 < 0) Then
num3 = (num3 + &H7FFFFFFF)
End If
num2 = Me.SeedArray(index)
Next i
Dim j As Integer
For j = 1 To 5 - 1
Dim k As Integer
For k = 1 To &H38 - 1
Me.SeedArray(k) = (Me.SeedArray(k) - Me.SeedArray((1 + ((k + 30) Mod
&H37))))
If (Me.SeedArray(k) < 0) Then
Me.SeedArray(k) = (Me.SeedArray(k) + &H7FFFFFFF)
By using our site, you acknowledge
End If
that you have read and understand our Cookie Policy, Privacy Policy, and
our Terms of Service. Next k
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 9/11
5/6/2020 Random integer in VB.NET - Stack Overflow
Next j
Me.inext = 0
Me.inextp = &H15
Seed = 1
End Sub
<__DynamicallyInvokable> _
Public Overridable Function [Next]() As Integer
Return Me.InternalSample
End Function
<__DynamicallyInvokable> _
Public Overridable Function [Next](ByVal maxValue As Integer) As Integer
If (maxValue < 0) Then
Dim values As Object() = New Object() { "maxValue" }
Throw New ArgumentOutOfRangeException("maxValue",
Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", values))
End If
Return CInt((Me.Sample * maxValue))
End Function
<__DynamicallyInvokable> _
Public Overridable Function [Next](ByVal minValue As Integer, ByVal maxValue As
Integer) As Integer
If (minValue > maxValue) Then
Dim values As Object() = New Object() { "minValue", "maxValue" }
Throw New ArgumentOutOfRangeException("minValue",
Environment.GetResourceString("Argument_MinMaxValue", values))
End If
Dim num As Long = (maxValue - minValue)
If (num
By using our site, you <= &H7FFFFFFF)
acknowledge that you Then
have read and understand our Cookie Policy, Privacy Policy, and
Return (CInt((Me.Sample * num)) + minValue)
our Terms of Service . If
End
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 10/11
5/6/2020 Random integer in VB.NET - Stack Overflow
Return (CInt(CLng((Me.GetSampleForLargeRange * num))) + minValue)
End Function
<__DynamicallyInvokable> _
Public Overridable Sub NextBytes(ByVal buffer As Byte())
If (buffer Is Nothing) Then
Throw New ArgumentNullException("buffer")
End If
Dim i As Integer
For i = 0 To buffer.Length - 1
buffer(i) = CByte((Me.InternalSample Mod &H100))
Next i
End Sub
<__DynamicallyInvokable> _
Public Overridable Function NextDouble() As Double
Return Me.Sample
End Function
<__DynamicallyInvokable> _
Protected Overridable Function Sample() As Double
Return (Me.InternalSample * 4.6566128752457969E-10)
End Function
' Fields
Private inext As Integer
Private inextp As Integer
Private Const MBIG As Integer = &H7FFFFFFF
Private Const MSEED As Integer = &H9A4EC86
Private Const MZ As Integer = 0
Private SeedArray As Integer()
End Class
3 this is horrible. it's not random at all. it's only a precomputed number based on the time. this would not
exhibit any properties of a random number. plus it does not answer the question. the question was not how
to generate any random number but one between 1 and a given value. – Shawn Kovac Jan 30 '14 at 15:33
By using our site, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and
our Terms of Service.
https://stackoverflow.com/questions/18676/random-integer-in-vb-net 11/11