Why does Rnd work this way?
BlitzMax Forums/BlitzMax Beginners Area/Why does Rnd work this way?
| ||
I see that Rnd(min_val,max_val) works differently from Blitz3D inasmuch as max_val is exclusive. Why is this? So now how do i get a random number in the inclusive range 0.0 to 1.0, for example? I also see that Rand()'s parameters are both inclusive... |
| ||
scrub that... need to read better |
| ||
So now how do i get a random number in the inclusive range 0.0 to 1.0, for example? Just use Rnd(0,1). Never concerned myself with all that inclusive/exclusive lark. When you're returning a double the chances of that double being exactly 1 would be miniscule anyway. Just ran a couple of hundred iterations and the highest I got was 0.99442527370318512. Do you need it more precise than that? |
| ||
Do you need it more precise than that? Probably not, now you mention it. I was just wondering why it differed from the other blitz languages, really. I also need to get used to the increased precision offered by Doubles, as I've not had to use them in a good while. :) |
| ||
The floating point value Rnd(a,b) is in the range from a to b, where a is included but b is excluded. This is the way it works in all versions of Blitz and all other languages I can think of. It is a natural consequence of the way floats work. Imagine a simplified system with exactly three decimal digits. To generate a random float we generate three random digits. There are one thousand possible values uniformly distributed in the range 000 to 999. Now we put a decimal point at the front to get values from .000 to .999, which includes 0 but not 1. So that's our random x from 0 to 1, with 1 excluded. For the range a to b we generate x as before, then calculate ( a + x * ( b - a ) ). This ranges from a to b ,with b excluded. That's exacly how Rnd() works, except with random binary bits instead of random decimal digits. |
| ||
Well, the Blitz3D docs say: This returns either a floating point or integer number of a random value falling between the start and end number. It returns an integer if assiged to an integer variable, and it returns a floating point value if assiged to a floating number variable. The start and end values are inclusive. Your explanation does make sense though, Floyd. Maybe the docs are wrong - wouldn't be the first time. :) |
| ||
It returns an integer if assiged to an integer variable, and it returns a floating point value if assiged to a floating number variable. That's wrong no matter what else the function does. The returned value is always floating point, single precision for classic Blitz languages and double for BlitzMax. Of course, if assigned to an integer variable then the value is converted to an integer. For example "n% = Rnd(1,4)" can only produce the results 1,2,3 in BlitMax. But in earlier Blitz languages the conversion is done by rounding to the nearest integer. Hence the possible values are 1,2,3,4. This is no doubt the source of confusion about the end of the range being included. It also a source of error. The length of the interval is 3. The integer results 1,2,3 in BlitzMax are equally likely, each occuring about 1/3 of the time. But the 1,2,3,4 of older Blitzes are not equally likely. The 2 and 3 each have probability 1/3, but the 1 and 4 split the other 1/3. This was particularly problematic in Blitz's early days when there was no Rand function. |
| ||
Sheesh, talk about lazy! I've just now read the Blitz3D description of Rnd() all the way through. It actually uses the faulty "y = Rnd(0,10)" in the example code. Here is a demostration of the difference. In BlitzMax the numbers 1,2,3 occur with counts near 1000,1000,1000. In Blit3D the numbers 1,2,3,4 occur with counts near 500,1000,1000,500. Global count[5] ;' This array syntax works with both BlitzMax and Blitz3D etc. Print Print " Count occurences of 1,2,3,4." Print For n = 1 To 3000 r = Rnd(1,4) count[r] = count[r] + 1 Next For n = 1 To 4 Print n + " " + count[n] Next WaitKey |
| ||
@Big10p: I never knew that, but I too don't worry about it as that chance of hitting a full rounded integer as the top number is so rate. |
| ||
Interesting stuff, Floyd! |
| ||
Rand is inclusive though e.g. For x=1 To 100000 random=Rand(1,10) If random=10 RuntimeError "arg" EndIf Next |
| ||
I know, I mentioned that in my first post. ;) |