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)
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
Re: Unsigned Long random number help
Quote:
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.
Re: Unsigned Long random number help
Quote:
Originally Posted by
dbasnett
Don't declare the random inside the Function.
Yes. The words of wisdom.
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
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 :))
Re: Unsigned Long random number help
Quote:
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.
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.
Re: Unsigned Long random number help
Quote:
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.
Re: Unsigned Long random number help
Quote:
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.