[AccessD] Rnd as Double (was: Create a random date/time)
Gustav Brock
gustav at cactus.dk
Wed Sep 5 08:00:51 CDT 2018
Hi all
I wondered how to generate a pseudo random value as a double - like Rnd does for a single.
This, I believe, can be done by calling Rnd twice, shifting one of the values "below the range of a single", and add the two values, thus obtaining more significant digits.
It is simpler than it may sound:
<code>
Public Function RndDbl(Optional ByRef Number As Single) As Double
' Exponent to shift the significant digits of a single to
' the least significant digits of a double.
Const Exponent As Long = 7
Dim Value As Double
' Generate two values like:
' 0.1851513
' 0.000000072890967130661
' and add these.
Value = CDbl(Rnd(Number)) + CDbl(Rnd(Number) * 10 ^ -Exponent)
' Return value like:
' 0.185151372890967
RndDbl = Value
End Function
</code>
Then call it with a dynamic seed using Timer:
PseudoRandomDouble = RndDbl(-Timer)
What do you think?
/gustav
PS: I posted here on 2015-08-31 a replacement for the date function below.
-----Oprindelig meddelelse-----
Fra: AccessD <accessd-bounces at databaseadvisors.com> På vegne af Stuart McLachlan
Sendt: 29. august 2015 03:22
Til: Access Developers discussion and problem solving <accessd at databaseadvisors.com>
Emne: Re: [AccessD] Create a random date/time
Rnd * Rnd is NOT a "trick to create a random date/time".
It is a trick to create "more significant digits" than the Single returned by a Rnd.
Unfortunately it has a VERY bad side effect. Multiplying random numbers together alters the probablility distribution. http://mathworld.wolfram.com/UniformProductDistribution.html
A better way would be to use Rnd twice in a different way. First to generate the Date part and a second time to generate the time part, then add then together.
--
Stuart
On 28 Aug 2015 at 15:29, Gustav Brock wrote:
> Hi all
>
> Have you ever wondered how to create a random date/time?
>
> Well I hadn't, but it is not that difficult. The trick is using Rnd
> twice:
>
> RandomDate = CDate((CLng(#12/31/9999#) - CLng(#1/1/100#)) * Rnd *
> Rnd + CLng(#1/1/100#))
>
> The full story is here:
>
> http://stackoverflow.com/a/32265346/3527297
>
> If you want a value within a given range, you can use this simple
> function:
>
> <code>
> Public Function DateRandom( _
> Optional ByVal UpperDate As Date = #12/31/9999#, _
> Optional ByVal LowerDate As Date = #1/1/100#) _
> As Date
>
> ' Generates a random date/time - optionally within the range of
> LowerDate and/or UpperDate. ' ' 2015-08-28. Gustav Brock, Cactus
> Data ApS, CPH.
>
> Dim RandomDate As Date
>
> RandomDate = CDate((CLng(UpperDate) - CLng(LowerDate)) * Rnd * Rnd
> + CLng(LowerDate))
>
> DateRandom = RandomDate
>
> End Function
> </code>
>
> /gustav
More information about the AccessD
mailing list