×
The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.
It falls back on the random number issue.....
OK, so you want to convert the 8F coming from CEERAN0 to an integer.
The idea behind CEERAN0 is that is returns a floating point number
between 0 and a number very near (but not touching) 1. There's more to
it, but that's the part you're interested in at the moment.
So your job is to map this infinite number space to a finite set of
integers. The good news is that this has been done before :-) There
are a variety of ways to do this. You can think of those random numbers
as occurring in ranges:
.00001 to .10000
.10001 to .20000 and so on. You could use a select/when group to bin
the range into an integer; this particular binning would result in
integers from 1 to 10. Or 0 through 9. Or 21 through 30. Whatever you
choose to put in your EVAL inside the WHEN.
when float <= .10000
eval rnd = 1
when float <= .20000
eval rnd = 2
It'll be hard to make a generic routine out of those comparisons, but
it's easier to understand how the numbers are distributed by performing
this mental exercise.
If you wanted integers between 1 and 10, and you're getting numbers
between 0 and .99999 (etc) then you can see that you need to multiply
the float in order to scale it up where you want it. A few minutes
noodling with a calculator will show that simply multiplying by 10 will
get you numbers between 0 and 9.9999. In RPG, we need to consider
intermediate precision: read the fine manual!!!!! One formula that can
help is:
callp ceeran0(seed: float: *omit)
rnd = (%dech(float:63:62) * max) + 1
The %DECH converts the float to a number that has a real lot of decimal
places, which preserves as much of the original distribution of the
floats as possible. Multiplying it by the maximum number (10) will
scale that tiny decimal between 0 and (almost) MAX. Adding 1 will move
the entire scaled range up one full integer from 1 to MAX.
This is all you need if your range is between 1 and some other positive
integer. If you need a different minimum, you'll need to throw away
numbers lower than any returned by this algorithm and generate a new one.
100000 passes of this algorithm resulted in this distribution from 1-10:
(1) 10037
(2) 9782
(3) 10064
(4) 10106
(5) 9909
(6) 10020
(7) 10015
(8) 10010
(9) 9926
(10) 10131
Hope that helped some. Be careful of the seed you choose; if you
choose the same seed (like a constant) you will generate the exact same
sequence of random numbers every time, and that's the way it's supposed
to work. By using an intial seed of zero, CEERAN0 will use a seed
derived from UTC (Universal Time Coordinated.)
http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/apis/CEERAN0.htm
--buck
As an Amazon Associate we earn from qualifying purchases.