Difference between revisions of "LlFrand"

From Second Life Wiki
Jump to navigation Jump to search
m (killed duplication)
Line 10: Line 10:
|return_type=float
|return_type=float
|return_text=that is pseudo random number in the range {{Interval|gte=0.0|lt='''mag'''|lth=mag|center=return}} or {{Interval|lte=0.0|gt='''mag'''|gth=mag|center=return}}.{{Interval/Footnote}}<br/> The sign of '''mag''' matches the return.
|return_text=that is pseudo random number in the range {{Interval|gte=0.0|lt='''mag'''|lth=mag|center=return}} or {{Interval|lte=0.0|gt='''mag'''|gth=mag|center=return}}.{{Interval/Footnote}}<br/> The sign of '''mag''' matches the return.
*In the format of llFrand( float mag -/+ float num ) -/+ float num
|caveats=*The random number generator is not a source of entropy.
|caveats=*The random number generator is not a source of entropy.
**The sequence of random numbers are shared across the entire process, and not independently seeded. Therefore, the pseudo random number generation is not suitable for any application which requires completely predictable or completely unpredictable results.
**The sequence of random numbers are shared across the entire process, and not independently seeded. Therefore, the pseudo random number generation is not suitable for any application which requires completely predictable or completely unpredictable results.
*It should be remembered that when passing llFrand an [[integer]] as the '''mag''', it will by implicitly [[typecast]] to a [[float]]. If the integer is outside the range {{NoWrap|[-2<sup>23</sup>, +2<sup>23</sup>]}} it may not be accurately represented (this is an inherent limitation of the float type). Likewise when using llFrand to generate a random integer, it cannot contain more than 24 random bits.
*It should be remembered that when passing llFrand an [[integer]] as the '''mag''', it will by implicitly [[typecast]] to a [[float]]. If the integer is outside the range {{NoWrap|[-2<sup>23</sup>, +2<sup>23</sup>]}} it may not be accurately represented (this is an inherent limitation of the float type). Likewise when using llFrand to generate a random integer, it cannot contain more than 24 random bits.
|examples=<lsl>// Tosses a coin, giving a *near* 50:50 chance of a result.


|examples=
<lsl>
//to randomise in a range from 2 to 5 for example.
llFrand(4.0) + 2
// llFrand goes from 0.0 to 4.0
// with the + 2 it is changed to 2.0 to 5.0
llFrand(6.0 + 3.0)
// llFrand goes from 0.0 to 8.0
</lsl>
<lsl>// Tosses a coin, giving a *near* 50:50 chance of a result.
integer coin_toss()
integer coin_toss()
{
{

Revision as of 12:35, 4 February 2011

Summary

Function: float llFrand( float mag );

Returns a float that is pseudo random number in the range [0.0, mag) or (mag, 0.0].[1]
The sign of mag matches the return.

  • In the format of llFrand( float mag -/+ float num ) -/+ float num
• float mag Any valid float value

Caveats

  • The random number generator is not a source of entropy.
    • The sequence of random numbers are shared across the entire process, and not independently seeded. Therefore, the pseudo random number generation is not suitable for any application which requires completely predictable or completely unpredictable results.
  • It should be remembered that when passing llFrand an integer as the mag, it will by implicitly typecast to a float. If the integer is outside the range [-223, +223] it may not be accurately represented (this is an inherent limitation of the float type). Likewise when using llFrand to generate a random integer, it cannot contain more than 24 random bits.
All Issues ~ Search JIRA for related Bugs

Examples

<lsl> //to randomise in a range from 2 to 5 for example. llFrand(4.0) + 2 // llFrand goes from 0.0 to 4.0 // with the + 2 it is changed to 2.0 to 5.0 llFrand(6.0 + 3.0) // llFrand goes from 0.0 to 8.0 </lsl> <lsl>// Tosses a coin, giving a *near* 50:50 chance of a result. integer coin_toss() {

 if( llFrand(1.) < .5 ) return TRUE;
 return FALSE;

}

// Sometimes it is useful to get a random integer over a given range. This is a surprisingly tricky and emotive subject // and has caused endless discussion on the scripting groups. // The primary cause of probability errors when employing llFrand is to have a varying bin size on the edges of the range. // // As the bracket notation indicates, [0.0,mag), the function is inclusive of the 0.0 and exclusive of the entered value. // Because an LSL floating point number is only a subset of real numbers and does not have infinite granularity, this schema // will work for any float greater than float t = 1.175494351e-38; at which value the function will // return only zero. At a float beyond this, a math error occurs.

// Random integer generator // Contributed by Mephistopheles Thalheimer, original function posited by Hg Beeks

// Returns a pseudo-random integer in the range of min to max inclusive.

// Rationale: Expands the range by 1.0 to ensure equal bin spacing on ends relative to the middle of // the range and then uses an integer cast to round towards zero.

// Caveats: This function is not range checked and will fail if max < min

integer random_integer( integer min, integer max ) {

 return min + (integer)( llFrand( max - min + 1 ) );

}

default {

   touch_start(integer total_number)
   {
       // When touched, say "Heads" with probability 0.5, 
       // otherwise, say "Tails."
       if ( coin_toss() )
           llSay(0, "Heads");
       else
           llSay(0, "Tails");

       integer n1 = random_integer( 2, 8 ); // Return a random number between 2 and 8
       llSay( PUBLIC_CHANNEL, "I chose a " + (string)n1 );

   }

}</lsl>

<lsl>// Simple integer random number tester // Contributed by Mephistopheles Thalheimer

// This is a random number tester designed to give a quick visual explanation and proof of why some // random integer functions just do not work. // In general, with any random number generator, if you can see a pattern emerging, then chances are, // the function is not random.

// The test case given "silly_random_integer( .. )" shows the type of pitfalls that can happen. Superficially, // it would seem like a good candidate. I thought so, and in fact mooted it in a discussion, however, a bit of thought reveals // that the first and last bin are only collecting rounded results from half the float space as the rest of the integers. // They are therefore under-represented in output, and the generator is flawed.


integer random_integer( integer min, integer max ) {

 return min + (integer)llFrand( max - min + 1 );

}

integer silly_random_integer( integer min, integer max ) {

 return min + (integer)( llRound( llFrand( max - min ) ) );  // Looks good, but does not work

}


// Simple integer random number tester // Contributed by Mephistopheles Thalheimer

list bins;

integer MIN = 2; // The minimum integer you want integer MAX = 5; // The maximum integer you want

integer NUMBER_OF_TRIES = 10000; // The bigger the better.. but slower

default {

   state_entry()
   {
       llSay( PUBLIC_CHANNEL, "Bin tester ready.");
       bins = [];
   }
   touch_start(integer total_number)
   {
       
       llSay( PUBLIC_CHANNEL, "Started, be patient" );
       
       integer i;
       integer r;
       
       integer range = MAX - MIN;
       
       for( i = 0; i <= range; ++i )
       {
           bins += [ 0 ];    
       }
       
       integer v;
       integer out_of_range;
       
       for( i = 0; i < NUMBER_OF_TRIES; ++i )
       {
           r = silly_random_integer( MIN, MAX );   // Replace this with the function you are testing
                                                   // Note the output on this one has about 0.5 expected hits on the first and last bin
           //r = random_integer( MIN, MAX );
           
if( r > MAX

Useful Snippets

Pseudo-random_Number_Generator - Suitable for apps which require repeatable results that feel random.

See Also

Functions

•  llListRandomize

Deep Notes

Search JIRA for related Issues

Footnotes

  1. ^ The ranges in this article are written in Interval Notation.

Signature

function float llFrand( float mag );