# 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 &lt;=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 ...

1. ## 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. ## 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. ## Re: Converting Rexx random() to real number on [0,1)

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. ## 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. ## 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. ## 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. ## 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:

>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. ## 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