[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