-
Jul 19th, 2011, 05:13 PM
#1
Thread Starter
New Member
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)
-
Jul 20th, 2011, 02:04 AM
#2
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:
' ''' <summary> ''' Returns a random date in between the two given dates ''' </summary> ''' <param name="date1">The start date of a period</param> ''' <param name="date2">The end date of a period</param> ''' <returns>Random date between date1 and date2</returns> ''' <remarks></remarks> Private Function GetRandomDateInBetween(ByVal date1 As Date, ByVal date2 As Date) As Date Dim diff As TimeSpan = date2 - date1 Dim numericdiff As Double = diff.TotalDays Dim rng As New Random() Dim randomvalue As Double = rng.NextDouble() * Math.Abs(numericdiff) If numericdiff >= 0 Then Return date1.AddDays(randomvalue) Else Return date2.AddDays(randomvalue) End If End Function
-
Jul 20th, 2011, 06:43 AM
#3
Re: Unsigned Long random number help
Originally Posted by cicatrix
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:
'
''' <summary>
''' Returns a random date in between the two given dates
''' </summary>
''' <param name="date1">The start date of a period</param>
''' <param name="date2">The end date of a period</param>
''' <returns>Random date between date1 and date2</returns>
''' <remarks></remarks>
Private Function GetRandomDateInBetween(ByVal date1 As Date, ByVal date2 As Date) As Date
Dim diff As TimeSpan = date2 - date1
Dim numericdiff As Double = diff.TotalDays
Dim rng As New Random()
Dim randomvalue As Double = rng.NextDouble() * Math.Abs(numericdiff)
If numericdiff >= 0 Then
Return date1.AddDays(randomvalue)
Else
Return date2.AddDays(randomvalue)
End If
End Function
Don't declare the random inside the Function.
-
Jul 20th, 2011, 07:52 AM
#4
Re: Unsigned Long random number help
Originally Posted by dbasnett
Don't declare the random inside the Function.
Yes. The words of wisdom.
-
Jul 20th, 2011, 08:17 AM
#5
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
-
Jul 20th, 2011, 08:59 AM
#6
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 -
-
Jul 20th, 2011, 09:18 AM
#7
Re: Unsigned Long random number help
Originally Posted by stanav
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.
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.
-
Jul 20th, 2011, 09:25 AM
#8
Re: Unsigned Long random number help
Originally Posted by ForumAccount
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 -
-
Jul 20th, 2011, 09:28 AM
#9
Re: Unsigned Long random number help
Originally Posted by stanav
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.
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|