Don't click here unless you want to be banned.

LSL Wiki : llFrand

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl338.us.archive.org
float llFrand(float max)

Returns a random float x from the interval [0.0, max), that is, 0.0 <= x < max. Ideally, the values returned would be uniformally distributed, but it has been reported that they are not very uniform.

To get a random float from (min, max) use something like

float randBetween(float min, float max)
{
    return llFrand(max - min) + min;
}

Integers


There are many cases where a random integer value would be useful: lists, channels, constants, etc. Try something like
integer randInt(integer n)
{
     return (integer)llFrand(n + 1);
}

integer randIntBetween(integer min, integer max)
{
    return min + randInt(max - min);
}

It should be noted, that llFrand can only ever return 24 random bits.

Rounding

There are a couple different functions for converting a float to an integer, in addition to casting. They will not yield evenly distributed results. The correct solution is to use an integer typecast (integer).

//right way
integer random = (integer)llFrand(4.0);//will return an integer 0 to 3, all with equal probabilities (more or less).

A first idea might be to use llRound but that has problems with the distributions. For example:

//wrong, do not do this.
integer random = llRound(llFrand(4.0));

In this case the values will range from 0 to 4 which is more intuitively obvious than the example below. However, the values returned by llFrand that will result in the integer 0 range from 0.0 to 0.5, and the values that will result in the integer 1 will be 0.5000001 to 1.5. As you can see the range for integer 1 is twice as large. That means a 1 will be "randomly" generated twice as often as a 0 which is probably not desired. The same effect happens at the far end with the integer 4.

Using llCeil is a bit safer, but still wrong:

//still wrong, do not do this (unless the input to llFrand is negitive, at which point it will do the same thing as an integer typecast)
integer random = llCeil(llFrand(4.0));

By rounding up it seems like this would result in a straight forward range from 1 to 4. It's unlikely, but possible, that llFrand will return a pure 0.0 value. In that case llCeil will not round up and it will return anomalous 0 values in very disproportionate frequency to the other values. The 0 is actually stealing that bit of probability from the 4, so an integer 4 will be infinitesimally less likely to occur than the others.

//still wrong, do not do this (unless the input to llFrand is positive, at which point it will do the same thing as an integer typecast)
integer random = llFloor(llFrand(5.0));

Using 5.0 for the input isn't obvious but results in float numbers between 0.0 and 4.99999. The floor function truncates the decimal. This results in values of 0 through 4. This is a perfect distribution of probability and the numbers drop right into list usage being zero indexed. So think of the input number as how many possible integers desired and, remember, they start with 0. But if input to llFrand is negitive this will have the same problem as llCeil

Solutions

The correct solution is to use the (integer) typecast. For example, to get a random integer ranging from 0 to 4:

integer random = (integer) llFrand (5.0);


image courtesy of http://xkcd.com/


Functions | Math
There are 16 comments on this page. [Display comments/form]