5
blah = CInt(Int((7 * Rnd()) + 0))

Generates a random integer between 0 and 6.

How can I modify this to give me a random number with 2 decimal places, still between 0 and 6?

As suggested below, I'm now using this code, and it seems to work:

Dim prng As New Random

Private Function aRand() As Double
    Return Math.Round(prng.Next(0, 601) / 100, 2)
End Function

currentApp.statements(Pick, 7) = aRand()
currentApp.statements(Pick, 8) = aRand()

Thanks for all the suggestions.

finisterre
  • 331
  • 7
  • 19

4 Answers4

3

Like this

Dim prng As New Random

Private Function aRand() As Double
    Return prng.Next(0, 601) / 100
End Function

note that the location of the random.

Your code would look like

    currentApp.statements(Pick, 7) = aRand()
    currentApp.statements(Pick, 8) = aRand()
dbasnett
  • 11,334
  • 2
  • 25
  • 33
2

The OP says between 0.00 and 6.00, so I believe that the advice from @HansPassant is the best to try but enlarging the upper limit to 601 ( if he means the limits are inclusive of course)

Dim rnd As New Random
Dim x As Integer = rnd.Next(0, 601)
Dim d = x / 100
Console.WriteLine(d)
Steve
  • 213,761
  • 22
  • 232
  • 286
2

Based on @Steve's answer, here is a generic implementation:

Function RandomDouble(maxValue As Integer, precision As Integer) As Double
  Static rnd As New Random
  Dim scale As Double = 10 ^ precision
  Dim x As Integer = rnd.Next(0, maxValue * scale + 1)
  Return x / scale
End Function

And the usage (tested in an empty console app, sub main):

Dim dbl As Double = RandomDouble(6, 2)
Debug.WriteLine(dbl)

So you can reuse it like this:

currentApp.statements(Pick, 7) = RandomDouble(6, 2)
currentApp.statements(Pick, 8) = RandomDouble(6, 2)

Or with DRY principle (=don't repeat yourself):

For i As Integer = 7 To 8
  currentApp.statements(Pick, i) = RandomDouble(6, 2)
Next
Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
  • How can this work? the Generic one.. if Random.Next() only accepts `Integers` and scale is a `Double` yeah I tested it, it raises a error `'minValue' cannot be greater than maxValue. Parameter name: minValue` – SSpoke Nov 04 '15 at 05:25
  • @SSpoke: Which parameters are you using? Which results do you want to achieve? – Victor Zakharov Nov 04 '15 at 12:43
  • Next() of Random library that's standard in .NET Framework only accepts Integers and scale is a `Double` can't really say anything other then that.. I fixed it.. I'll paste you my code. http://pastebin.com/scNZnM6m my needs needed a random decimal point value with a static value before the decimal point. – SSpoke Nov 06 '15 at 03:35
  • @SSpoke: After changing `Dim rnd` to `Static rnd` (thank you for noticing an issue, otherwise it generates identical data in all passes), and given arguments (maxValue=6,precision=2), it generates `3.72, 2.09, 5.82, 1.71, 0.7, 0.31, 4.63, 5.4, 3.95, 3.43, 1.75`, which looks right to me. If you need a constant value before decimal point, you need to use my function with arguments (maxValue=1,precision=?) and add to your fixed value. There is no need to write a separate function for that. – Victor Zakharov Nov 06 '15 at 13:20
0

I thought I would throw my hat in the ring on this question because I just expanded on @dbasnett answer to make a nice generic generator.

Note: I used Decimal but Double can be substituted as the output with no seen issues.

''' <summary>
''' Random Decimal generator with variable precision"
''' </summary>
''' <param name="L">Minimum Value</param>
''' <param name="U">Maximum Value</param>
''' <param name="P">Precision</param>
''' <returns>Decimal</returns>
''' <remarks></remarks>
Private Function DRandom(L As Integer, U As Integer, P As Integer) As Decimal
    Dim Rand As New Random
    Dim Upper As String = U.ToString
    Dim Precision As String = "1"
    For I = 0 To P
        If I > 0 Then
            If I = P Then
                Upper = Upper + "1"
            Else
                Upper = Upper + "0"
            End If
            Precision = Precision + "0"
        End If
    Next
    Return Rand.Next(L, Upper.toInteger) / Precision.toInteger
End Function

With my generic toInteger extension:

''' <summary>
''' Handles conversion of variable to Integer.
''' </summary>
''' <param name="X"></param>
''' <param name="I">Returned if conversion fails.</param>
''' <returns>Signed 32bit Integer</returns>
''' <remarks></remarks>
<Runtime.CompilerServices.Extension()> _
Public Function toInteger(Of T)(ByRef X As T, Optional I As Integer = 0) As Integer
    Dim S As String = X.ToString
    Try
        If S = String.Empty Then
            Return I
        Else
            Return Integer.Parse(S)
        End If
    Catch
        Dim result As String = String.Empty
        Dim ReturnInt As Integer
        Dim Parsed As Byte
        For Each Character In S.ToCharArray
            If Character = "-" Then
                If S.Substring(0, 1).ToString <> "-" Then
                    result = Character + result
                End If
            End If
            If Character = "." Then
                Exit For
            End If
            If Byte.TryParse(Character, Parsed) Then
                result = result + Parsed.ToString
            End If
        Next
        If result <> String.Empty Then
            If Integer.TryParse(result, ReturnInt) Then
                Return Integer.Parse(ReturnInt)
            Else
                If Double.Parse(result) > Double.Parse(Integer.MaxValue.ToString) Then
                    Return Integer.MaxValue
                ElseIf Double.Parse(result) < Double.Parse(Integer.MinValue.ToString) Then
                    Return Integer.MinValue
                Else
                    Return I
                End If
            End If
        Else
            Return I
        End If
    End Try
End Function

This generator takes a variable precision as well as letting you choose in the code what the upper and lower bounds are allowing for (in my opinion) maximum re-usability for a random number generator.

Hope this helps people.

ARidder101
  • 315
  • 2
  • 6
  • 16