Results 1 to 9 of 9

Thread: Unsigned Long random number help

  1. #1

    Thread Starter
    New Member
    Join Date
    May 2009
    Posts
    3

    Unsigned Long random number help

    I'm trying to generate random dates in between two dates that are selected with a date and time selection control.

    Ideally, I would like to get the 'ticks' of each date, generate a random number between those, and then convert that back into a date.

    However I'm getting arithmetic overflow errors when I try to generate a random number from the between the ticks. I've tried many approaches - directly seeding with both the low and high date ticks, as well as subtracting.

    Code:
       
    Private Function randomDate() As ULong
            Dim rand As New Random(Date.Now.Ticks Mod Integer.MaxValue)
    
            Dim holder As ULong = DateTimePicker2.Value.Ticks - DateTimePicker1.Value.Ticks
    
            return rand.Next(holder)
    Code:
       
    Private Function randomDate() As ULong
            Dim rand As New Random(Date.Now.Ticks Mod Integer.MaxValue)
    
            return rand.Next(DateTimePicker1.Value.Ticks, DateTimePicker2.Value.Ticks)

  2. #2
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Unsigned Long random number help

    Why do you need ticks while integers are sufficient? Do you need 'random date' or 'random date-time'?
    The first one is solved quite simply - by using days instead of ticks


    vb Code:
    1. '
    2.     ''' <summary>
    3.     ''' Returns a random date in between the two given dates
    4.     ''' </summary>
    5.     ''' <param name="date1">The start date of a period</param>
    6.     ''' <param name="date2">The end date of a period</param>
    7.     ''' <returns>Random date between date1 and date2</returns>
    8.     ''' <remarks></remarks>
    9.     Private Function GetRandomDateInBetween(ByVal date1 As Date, ByVal date2 As Date) As Date
    10.         Dim diff As TimeSpan = date2 - date1
    11.  
    12.         Dim numericdiff As Double = diff.TotalDays
    13.         Dim rng As New Random()
    14.  
    15.         Dim randomvalue As Double = rng.NextDouble() * Math.Abs(numericdiff)
    16.         If numericdiff >= 0 Then
    17.             Return date1.AddDays(randomvalue)
    18.         Else
    19.             Return date2.AddDays(randomvalue)
    20.         End If
    21.     End Function

  3. #3
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,748

    Re: Unsigned Long random number help

    Quote Originally Posted by cicatrix View Post
    Why do you need ticks while integers are sufficient? Do you need 'random date' or 'random date-time'?
    The first one is solved quite simply - by using days instead of ticks


    vb Code:
    1. '
    2.     ''' <summary>
    3.     ''' Returns a random date in between the two given dates
    4.     ''' </summary>
    5.     ''' <param name="date1">The start date of a period</param>
    6.     ''' <param name="date2">The end date of a period</param>
    7.     ''' <returns>Random date between date1 and date2</returns>
    8.     ''' <remarks></remarks>
    9.     Private Function GetRandomDateInBetween(ByVal date1 As Date, ByVal date2 As Date) As Date
    10.         Dim diff As TimeSpan = date2 - date1
    11.  
    12.         Dim numericdiff As Double = diff.TotalDays
    13.         Dim rng As New Random()
    14.  
    15.         Dim randomvalue As Double = rng.NextDouble() * Math.Abs(numericdiff)
    16.         If numericdiff >= 0 Then
    17.             Return date1.AddDays(randomvalue)
    18.         Else
    19.             Return date2.AddDays(randomvalue)
    20.         End If
    21.     End Function
    Don't declare the random inside the Function.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  4. #4
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Unsigned Long random number help

    Quote Originally Posted by dbasnett View Post
    Don't declare the random inside the Function.
    Yes. The words of wisdom.

  5. #5
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,748

    Re: Unsigned Long random number help

    This should get you a random datetime between two datetimes, to the millisecond.

    Code:
        Dim prng As New Random 'only one random needed
    
        Private Function RandomDateBetween(datePast As DateTime, dateFuture As DateTime) As DateTime
            'get days part suitable for random
            Dim tsd As TimeSpan = TimeSpan.FromDays((dateFuture - datePast).Duration.Days + 1)
            'get time (in ms.) part suitable for random
            Dim tst As TimeSpan = TimeSpan.FromMilliseconds((dateFuture.TimeOfDay - datePast.TimeOfDay).Duration.TotalMilliseconds + 1)
    
            Dim daysToAdd As Integer = prng.Next(tsd.Days) 'how many days to add
            Dim msToAdd As Integer = prng.Next(CInt(tst.TotalMilliseconds)) 'how many ms. to add
            Return datePast.AddDays(daysToAdd).AddMilliseconds(msToAdd)
        End Function
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  6. #6
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,289

    Re: Unsigned Long random number help

    A simpler version, to the ticks
    Code:
     Private rng As New Random
        Private Function PickRandomDateBetween(ByVal fromDate As Date, ByVal toDate As Date) As Date
            Dim multiplier As Double = rng.NextDouble
            Do Until (multiplier > 0.0R)
                multiplier = rng.NextDouble
            Loop
            Return fromDate.AddTicks(CLng(multiplier * toDate.Subtract(fromDate).Ticks))
        End Function
    Per ForumAccount's suggestion in post#7, I've change the loop to test just if NextDouble > 0 since the return value is alreay always < 1.
    I also changed the literal type character from D to R (for some reason, I keep mixing those up )
    Last edited by stanav; Jul 20th, 2011 at 09:52 AM. Reason: ETo conform to ForumAccount's suggestion in post #7 below.
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  7. #7
    Master Of Orion ForumAccount's Avatar
    Join Date
    Jan 2009
    Location
    Canada
    Posts
    2,802

    Re: Unsigned Long random number help

    Quote Originally Posted by stanav View Post
    A simpler version, to the ticks
    Code:
     Private rng As New Random
        Private Function PickRandomDateBetween(ByVal fromDate As Date, ByVal toDate As Date) As Date
            Dim multiplier As Double = rng.NextDouble
            Do Until (multiplier > 0D AndAlso multiplier < 1D)
                multiplier = rng.NextDouble
            Loop
            Return fromDate.AddTicks(CLng(multiplier * toDate.Subtract(fromDate).Ticks))
        End Function
    NextDouble already returns a number between 0.0 and 1.0. So you don't actually need the loop.
    Quote Originally Posted by MSDN
    A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
    Also the literal type character 'D' forces a decimal. You should use 'R' for double.

  8. #8
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,289

    Re: Unsigned Long random number help

    Quote Originally Posted by ForumAccount View Post
    NextDouble already returns a number between 0.0 and 1.0. So you don't actually need the loop.
    Also the literal type character 'D' forces a decimal. You should use 'R' for double.
    We want a random date in between the 2 dates - not inclusive. That's why we need to make sure that NextDouble returns something 0< value < 1.
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  9. #9
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,748

    Re: Unsigned Long random number help

    Quote Originally Posted by stanav View Post
    We want a random date in between the 2 dates - not inclusive. That's why we need to make sure that NextDouble returns something 0< value < 1.
    I missed where the OP said that. The code I posted is inclusive of both dates.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width