Aries
New Member
I've seen many examples on the forum of using something like "random w0: w0 = w0 // n" to generate a random number in the range 0 to n-1. What I have recently realised is that while this does give a random number, it is not uniformly distributed - there is a greater likelihood of getting a number in the lower part of the range. In the case I was working on, I was looking for numbers in the range 0 to 28799 (the number of seconds in 8 hours - don't ask why). After running the function several thousand times, I was surprised to see that for every 1000 numbers in the range 0-143999, there were only 800 (or so) in the range 14400-28799. Having checked my program, and not seeing anything wrong, I did a bit of mathematical analysis.
To keep things simple, I'm going to use 32 rather than 65536 as the range for w0, and 6 for "n" - the range over which I want the random numbers. The pseudo-random number generator in Picaxe does, I think, produce all the numbers in the given range, but effectively in a random order. So, after 32 executions of the function, you have generated each of the numbers 0-31 once. Using the formula w0 // n, the numbers 0-31 give the numbers 0-5, 0-5, 0-5, 0-5, 0-5, 0-1. So, 0 and 1 occur 6 times but 2-5 occur 5 times, a bias towards 0 and 1 as the result.
Before I saw the use of // to get random numbers, I was using **. In fact, this replicates the more usual form of random numbers, where - for example - the spreadsheet function RAND() gives a number in the range 0-1, which is then multiplied by "n" to give a number in the range 0 to n-1. w0 = w0 ** n is effectively the same as w0 = n * (w0/65536) and gives a much closer approximation to a uniform distribution of random numbers across the range 0 to n-1.
To keep things simple, I'm going to use 32 rather than 65536 as the range for w0, and 6 for "n" - the range over which I want the random numbers. The pseudo-random number generator in Picaxe does, I think, produce all the numbers in the given range, but effectively in a random order. So, after 32 executions of the function, you have generated each of the numbers 0-31 once. Using the formula w0 // n, the numbers 0-31 give the numbers 0-5, 0-5, 0-5, 0-5, 0-5, 0-1. So, 0 and 1 occur 6 times but 2-5 occur 5 times, a bias towards 0 and 1 as the result.
Before I saw the use of // to get random numbers, I was using **. In fact, this replicates the more usual form of random numbers, where - for example - the spreadsheet function RAND() gives a number in the range 0-1, which is then multiplied by "n" to give a number in the range 0 to n-1. w0 = w0 ** n is effectively the same as w0 = n * (w0/65536) and gives a much closer approximation to a uniform distribution of random numbers across the range 0 to n-1.