[AccessD] Rnd as Double (was: Create a random date/time)

Gustav Brock gustav at cactus.dk
Mon Dec 23 06:29:52 CST 2019


Hi all

I have updated this to behave exactly like the native Rnd.
It is done by using a static to hold the last generated value..

<code>
' Returns a pseudo-random number as a Double, like Rnd returns a Single.
' The value will be less than 1 but greater than or equal to zero.
'
' Usage: Excactly like Rnd:
'
'   PseudoRandomValue = RndDbl[(Number)]
'
'   Number < 0  ->  The same number every time, using Number as the seed.
'   Number > 0  ->  The next number in the pseudo-random sequence.
'   Number = 0  ->  The most recently generated number.
'   No Number   ->  The next number in the pseudo-random sequence.
'
' 2019-12-21. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function RndDbl( _
    Optional ByVal Number As Single = 1) _
    As Double

    ' Exponent to shift the significant digits of a single to
    ' the least significant digits of a double.
    Const Exponent          As Long = 7
    
    Static Value            As Double
    
    Select Case Number
        Case Is <> 0 Or (Number = 0 And Value = 0)
            ' Return the next number in the pseudo-random sequence.
            ' Generate two values like:
            '   0.1851513
            '   0.000000072890967130661
            ' and add these.
            Value = CDbl(Rnd(Number)) + CDbl(Rnd(Number) * 10 ^ -Exponent)
        Case Is = 0
            ' Return the most recently generated number.
    End Select
    
    ' Return a value like:
    '   0.185151372890967
    RndDbl = Value
    
End Function
</code>

Merry Christmas!
Gustav

-----Oprindelig meddelelse-----
Fra: AccessD <accessd-bounces at databaseadvisors.com> På vegne af Gustav Brock
Sendt: 5. september 2018 15:01
Til: Access Developers discussion and problem solving <accessd at databaseadvisors.com>
Emne: [AccessD] Rnd as Double (was: Create a random date/time)

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 



More information about the AccessD mailing list