Converting Rexx random() to real number on [0,1) - REXX

This is a discussion on Converting Rexx random() to real number on [0,1) - REXX ; The Rexx random number generator returns an integer on [min,max] (endpoints included) where max-min <=100000. The Visual Basic random number generator returns a real (floating point) number on [0,1) (lower endpoint included, upper not). I would like to write a ...

+ Reply to Thread
Results 1 to 8 of 8

Converting Rexx random() to real number on [0,1)

  1. Default Converting Rexx random() to real number on [0,1)

    The Rexx random number generator returns an integer on [min,max]
    (endpoints included) where max-min <=100000.

    The Visual Basic random number generator returns a real (floating
    point) number on [0,1) (lower endpoint included, upper not).

    I would like to write a little function to convert the Rexx random
    function into the VB function for some testing.

    My first inclination was to generate the maximum range [0,100000] then
    divide by 100000:

    rmax = 10**5
    rnd = random(rmax)/rmax
    Return rnd

    This works great except for about every 100,000th call. Whenever it
    returns the upper limit of the range, my function returns a "1", which
    the VB function never does.

    My first thought was to divide by max+1:

    rmax = 10**5
    rnd = random(rmax)/(rmax+1)
    Return rnd

    This function will never return a "1". It creates 100001 evenly-spaced
    floating point numbers on [0,1), but the gap between 1 and the highest
    possible value is slightly larger than all of the other gaps.

    ? max = 100000

    ? b1 = 1/(max+1)
    ? say b1
    0.0000099999 /* Gap 1 is 0.0000099999 */

    ? b2 = 2/(max+1)
    ? say b2-b1
    0.0000099999 /* Gap 2 is 0.0000099999 */

    ? b3 = 3/(max+1)
    ? say b3-b2
    0.0000099999 /* Gap 2 is 0.0000099999 */

    ? bn = max/(max+1)
    ? say 1-bn
    0.00001 /* Gap n+1 is 0.00001 */

    Is there a better way to convert the Rexx RANDOM function to emulate
    the VB RND function?



    Is there a way to combine 2 random numbers to get a new set of random
    numbers on a larger range than 0-100000?


  2. Default Re: Converting Rexx random() to real number on [0,1)

    Three Lefts wrote:

    > Is there a way to combine 2 random numbers to get a new set of random
    > numbers on a larger range than 0-100000?


    Yes, you simply abut the output from two calls to random:

    Say random(0,99999)right(random(0,99999),5)

    You can add zero to get rid of the leading zero that you'll occasionally
    get:

    Say (random(0,99999)right(random(0,99999),5))+0

    I wrote myself a "bigrand"() function to extend this idea to any
    arbirary length. It is more complex that the simple approach above,
    because you run into non-randomness if your ranges are not multiples of ten.

    --
    Steve Swift
    http://www.swiftys.org.uk/swifty.html
    http://www.ringers.org.uk

  3. Default Re: Converting Rexx random() to real number on [0,1)

    In Message-ID:<6feqf45786egcpadgfnhj7cd9tp7k59fct@4ax.com>,
    Three Lefts <spamtrap@spamtrap.invalid> wrote:

    >My first thought was to divide by max+1:
    >
    > rmax = 10**5
    > rnd = random(rmax)/(rmax+1)
    > Return rnd
    >
    >This function will never return a "1". It creates 100001 evenly-spaced
    >floating point numbers on [0,1), but the gap between 1 and the highest
    >possible value is slightly larger than all of the other gaps.


    Try increasing your NUMERIC DIGITS setting. It works fine for me, as
    you can see from the output of my REXX calculator (CALCR):

    Ready for commands. Use "EXIT" to exit. Use "HELP" for help.
    let max=1e5
    00000000 000186A0 100,000
    let bn=max/(max+1)
    00000000 00000000 0.999990000099999000009999900001
    1-bn
    00000000 00000000 0.000009999900000999990000099999
    let b3=3/(max+1)
    00000000 00000000 0.000029999700002999970000299997
    let b2=2/(max+1)
    00000000 00000000 0.000019999800001999980000199998
    b3-b2
    00000000 00000000 0.000009999900000999990000099999
    curr-(1-bn)
    00000000 00000000 0

    --
    Arthur T. - ar23hur "at" intergate "dot" com
    Looking for a z/OS (IBM mainframe) systems programmer position

  4. Default Re: Converting Rexx random() to real number on [0,1)

    On Tue, 21 Oct 2008 05:45:38 +0100, Swifty <steve.j.swift@gmail.com>
    wrote:

    >Three Lefts wrote:
    >
    >> Is there a way to combine 2 random numbers to get a new set of random
    >> numbers on a larger range than 0-100000?

    >
    >Yes, you simply abut the output from two calls to random:
    >
    >Say random(0,99999)right(random(0,99999),5)


    Did you mean something like,

    random(99999)right(random(99999),5,0)

    ?

  5. Default Re: Converting Rexx random() to real number on [0,1)

    Three Lefts wrote:
    > Did you mean something like,
    >
    > random(99999)right(random(99999),5,0)


    Yes, of course, how silly of me. I even tested it in rexxtry, a few
    times, but obviously never got a number less than 10000 for the second
    random().

    --
    Steve Swift
    http://www.swiftys.org.uk/swifty.html
    http://www.ringers.org.uk

  6. Default Re: Converting Rexx random() to real number on [0,1)

    On Tue, 21 Oct 2008 08:51:34 +0100, Swifty <steve.j.swift@gmail.com>
    wrote:

    >Three Lefts wrote:
    >> Did you mean something like,
    >>
    >> random(99999)right(random(99999),5,0)

    >
    >Yes, of course, how silly of me. I even tested it in rexxtry, a few
    >times, but obviously never got a number less than 10000 for the second
    >random().


    Do you know of any "proof" that this composite random variable is no
    less "random" than a single?

    All computer-generated pseudo random number generators (PRNGs)
    generate repeating strings. If they use single precision floating
    point numbers, the string length is ~16 million. The PRNG starts at
    some "random" location in that string, usually based on the time, but
    then the sequence is 100% predictable.

    Since we are always using consecutive numbers in this PRNGs string, is
    the result less random?

  7. Default Re: Converting Rexx random() to real number on [0,1)

    On Tue, 21 Oct 2008 00:49:50 -0400, Arthur T. <arthur@munged.invalid>
    wrote:

    >In Message-ID:<6feqf45786egcpadgfnhj7cd9tp7k59fct@4ax.com>,
    >Three Lefts <spamtrap@spamtrap.invalid> wrote:
    >
    >>My first thought was to divide by max+1:
    >>
    >> rmax = 10**5
    >> rnd = random(rmax)/(rmax+1)
    >> Return rnd
    >>
    >>This function will never return a "1". It creates 100001 evenly-spaced
    >>floating point numbers on [0,1), but the gap between 1 and the highest
    >>possible value is slightly larger than all of the other gaps.

    >
    > Try increasing your NUMERIC DIGITS setting. It works fine for me, as
    >you can see from the output of my REXX calculator (CALCR):
    >
    >Ready for commands. Use "EXIT" to exit. Use "HELP" for help.
    >let max=1e5
    >00000000 000186A0 100,000
    >let bn=max/(max+1)
    >00000000 00000000 0.999990000099999000009999900001
    >1-bn
    >00000000 00000000 0.000009999900000999990000099999
    >let b3=3/(max+1)
    >00000000 00000000 0.000029999700002999970000299997
    >let b2=2/(max+1)
    >00000000 00000000 0.000019999800001999980000199998
    >b3-b2
    >00000000 00000000 0.000009999900000999990000099999
    >curr-(1-bn)
    >00000000 00000000 0


    OK, the gaps are equal. I should have known that.

    I made the wrong point. It's not the size, but the existence, of the
    gap. I am trying to generate a random number on [0,1), but what I am
    doing is generating a random number on [0,1-gap). The question is
    whether the gap is too large.

    Clearly no computer generated algorithm with finite memory can get
    infinitesimally close to 1, but a gap of 1E-5 seems too large.

    Suppose I use my new PRNG to randomly select one of 2 paths. The code
    might look like this:

    i=trunc(randomr()*2)+1


    ? numeric digits 20
    ? max = 100000

    ? bmax = max/(max+1)
    ? say bmax
    0.99999000009999900001
    ? say 1-bmax
    0.0000099999000010000

    Now let's see what the gap is just below 0.5. It should be about half
    of that below 1.0.

    ? bhalf=(max/2)/)max+1)
    ? say bhalf
    0.4999959999499995
    ? say .5-bhalf
    0.0000049999500005

    Roughly half. If I checked .25, it would be one quarter and so on.

    Another way to look at this is that the Rexx random function only has
    100001 unique values that it can return. This is way too small.

    If I use this to choose among 2 paths, one path will have 50,000
    chances and the other will have 50,001 chances. That's a difference of
    ..002% (.00002), which may be too much for some applications.

    If I am choosing among 3 paths, 2 will have 33,333 chances and the
    other will have 33,334. That's a difference of .003%.

    If I am choosing among 1,000 paths, 999 will have 100 chances, and 1
    will have 101 chances. Now the error is .1%.


    I think the conclusion is that using random() to simulate rnd is only
    good for rough approximations.

    Presumably, using random() directly to choose from n paths will have a
    smaller error, but I just ran a quickie simulation on 2 paths and
    after ~430,000 iterations, Path 2 was .14% behind.

  8. Default Re: Converting Rexx random() to real number on [0,1)

    Three Lefts wrote:
    > Do you know of any "proof" that this composite random variable is no
    > less "random" than a single?


    The problem came when you want to build a rand() function that takes the
    same arguments as random() but without the limits.

    Suppose you call it with rand(1,123456)

    My current code generates random numbers between 1 and 199999 then
    discards any that exceed the upper limit (123456). This is as random as
    the numbers that come from the built-in random() which it uses, but it
    can be wasteful, because it has to loop until it hits a number in the
    range.

    Previously I tried to develop a technology that didn't need the loop,
    but every attempt was biased, one way or another.

    My assumptions were based on the assumption that random() itself is
    truly random. This isn't true, but my code introduces no extra bias.


    --
    Steve Swift
    http://www.swiftys.org.uk/swifty.html
    http://www.ringers.org.uk

+ Reply to Thread