Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

generating random integers

0 views
Skip to first unread message

Bob O`Bob

unread,
May 16, 2008, 10:08:15 PM5/16/08
to
...or generating random Longs, whatever.


I am unsure if I have a flawed code fragment or if I am running into
the oft-mentioned shortcomings of VB's PRNG (psuedo-random number generator)

I have a function designed to return a random integer from within the
supplied range (inclusive) and the code looks like this:

Private Function MyRnd(lowerbound As Long, upperbound As Long) As Long
MyRnd= CLng((upperbound - lowerbound + 1) * Rnd + lowerbound)
End Function

I thought that I had derived this from the example in VB's own help files,
but now I see that the example there is far too simple.


Anyway, as a quality check, I've been looping a few tens of thousands
of times on it, accumulating the results, and I'm not liking what I see.

Did I get the formula wrong?
I can't seem to figure out where it really came from.

Bob
--

Jim Mack

unread,
May 16, 2008, 10:50:06 PM5/16/08
to
Bob O`Bob wrote:
> ...or generating random Longs, whatever.
>
>
> I am unsure if I have a flawed code fragment or if I am running into
> the oft-mentioned shortcomings of VB's PRNG (psuedo-random number
> generator)
>
> I have a function designed to return a random integer from within
> the supplied range (inclusive) and the code looks like this:
>
> Private Function MyRnd(lowerbound As Long, upperbound As Long)
> As Long MyRnd= CLng((upperbound - lowerbound + 1) * Rnd +
> lowerbound) End Function

The canonical method would be Int(Rnd * (UB - LB + 1)) + LB

CLng is not recommended because of its 'even' bias, and the LB should
be added after the Int.

I'm pretty sure that's been in the MS Basic docs since forever.

--
Jim

Richard Mueller [MVP]

unread,
May 16, 2008, 11:48:57 PM5/16/08
to
Bob wrote:

The Rnd function returns values greater than or equal to 0 and less than 1.
You should use the Randomize function once at the start to seed it. It has a
period of 2^24, so values repeat after 16,777,216 calls to the function.

The function internally produces a psuedo random integer between 0 and
16,777,215, then divides by 16,777,216.

I think the best way to generate longs between lowerbound and upperbound
would be:

MyRnd = Fix((upperbound - lowerbound + 1) * Rnd) + lowerbound

The CLng function rounds, so the max and min values are less likely than
other values. The Fix function takes the integer part. Values from 0.000 to
0.499 round to 0, while 0.5 to 1.499 round to 1 (twice as likely). But 0.000
to .999 Fix to 0, while 1.0 to 1.999 Fix to 1.

--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--


Bob O`Bob

unread,
May 17, 2008, 1:08:47 AM5/17/08
to
Jim Mack wrote:

> CLng is not recommended because of its 'even' bias, and the LB should
> be added after the Int.


Thanks! /That/ was what I was running into.


>
> I'm pretty sure that's been in the MS Basic docs since forever.
>

I thought something like it too, but the VB6 help versions seem
to show only the horribly simplified single example now.


Bob
--

0 new messages