LlFrand/ja

From Second Life Wiki
Jump to navigation Jump to search

要約

関数: llFrand( float mag );

範囲 [0.0, mag) または (mag, 0.0] の疑似乱数[1] を float で返します。
mag の符号と同じ符号が復帰値につきます。

• float mag 範囲内の任意の float 値

警告

  • この乱数ジェネレータの乱数発生源は無作為ではありません。
    • 乱数の並びはプロセス全体で共有され、毎回シードを設定するわけではありません。このため、疑似乱数生成は完全に予測可能な、もしくは完全に予測不可能な解を必要とするアプリケーションには適していません。
  • llFrand で任意の integermag に指定すると、暗黙のうちに float型変換 されることに注意しましょう。整数が [-223, +223] の範囲外である場合、同等とならない可能性があります (float 型の元々の制約です) 。同じように、 llFrand を使用して乱整数を発生させると、 24 個以上のランダムなビットは含まれません。
All Issues ~ Search JIRA for related Bugs

サンプル

// コインを投げて、 *だいたい* 五分五分の結果を出します。

integer coin_toss()
{
  if( llFrand(1.) < .5 ) return TRUE;
  return FALSE;
}

// 指定された範囲を超える整数を取得するのに便利なこともあります。
// スクリプトのグループで果てしない論争を巻き起こしてきた、ものすごくトリッキーで偏向的な方法です。
// llFrand を使用するときに陥りやすい間違いの主な原因は、範囲の端の bin の大きさが変わってしまうことにあります。
//
// [0.0,'''mag''') の括弧表記が物語るように、関数は 0.0 を含み、入力された値を含みません。
// LSL の浮動小数点数は実数のサブセットでしかなく、精度は無限ではないからです。
// このスキーマでは float t = 1.175494351e-38; より大きな float のジェネレータとしてうまく機能します。
// この数の場合、関数は 0 を返すことになります。この数より小さい場合、算術エラーが発生します。
  
// 乱整数ジェネレータ
// Contributed by Mephistopheles Thalheimer, original function posited by Hg Beeks

// min 以上 max 以下の疑似乱整数を返します。

// 原理: 範囲を 1.0 に拡張して、最後の bin の間隔が間の bin の間隔と同じになるにします。
// そして整数を 0 の方向に丸めてキャストします。

// 注意:  この関数は範囲のチェックをせず、 max < min だと落ちます。

integer random_integer( integer min, integer max )
{
  return min + (integer)( llFrand( max - min + 1 ) );
}

default
{
    touch_start(integer total_number)
    {
        // タッチしたとき、確率 0.5 で "Heads" と言い、
        // そのほかの場合は "Tails" といいます。 
        if ( coin_toss() )
            llSay(0, "Heads");
        else
            llSay(0, "Tails");
 
        integer n1 = random_integer( 2, 8 ); // 2 から 8 の間の乱数を返します
        llSay( PUBLIC_CHANNEL, "I chose a " + (string)n1 );
 
    }
}
// シンプルな乱整数テスター
// Contributed by Mephistopheles Thalheimer

// この乱整数テスターは、乱整数関数でうまく動かないものがある理由を、簡単に見てわかるように説明・証明するために書かれました。
// 一般的には、どんな乱数ジェネレータでも、パターンが現れたら、関数はランダムでない可能性があるとされます。

// "silly_random_integer( .. )" で指定されたテストケースでは陥る可能性のある落とし穴を示しています。
// 一見、いい候補のように見えます。私もそう思っていましたが、実際には、議論する中で、ちょっと考え直してみたところ、
// 最初と最後の bin は float で取りえる値の半分が整数に丸められたものであることに気がつきました。
// このため出力は同等でなく、ジェネレータは怪しげであることになります。


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 ) ) );  // いいように見えますが、うまくいきません
}


// シンプルな乱整数テスター
// Contributed by Mephistopheles Thalheimer

list bins;

integer     MIN             = 2;        // 欲しい最小値
integer     MAX             = 5;        // 欲しい最大値

integer     NUMBER_OF_TRIES  = 10000;    // 大きければ大きいほどいいですが.. 遅くなります

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 );   // これをテスト対象の関数に置き換えてください
                                                    // この結果は約 0.5 の確率で bin の最初と最後にヒットします。
            //r = random_integer( MIN, MAX );
            
            if( r > MAX || r < MIN )
            {    
               out_of_range++;
            }
            else
            {
               v = llList2Integer( bins, r - MIN );
               bins = llListReplaceList( bins, [ ++v ], r - MIN, r - MIN );
            }
        }

        for( i = 0; i <= range; ++i )
        {
            llOwnerSay( "Bin #" + (string)( i + MIN ) + " = " + (string)llList2Integer( bins, i ) );    
        }
        
        llOwnerSay( "Number out of range = " + (string)out_of_range );
    }
}

便利なスニペット

Pseudo-random_Number_Generator - ランダムに見える解を繰り返し必要とするアプリケーションに適しています。

関連項目

関数

•  llListRandomize

特記事項

Search JIRA for related Issues

脚注

  1. ^ 記事中の範囲は、 実数空間 に記載されているものです。

Signature

function void llFrand( float mag );
この翻訳は 原文 と比べて古いですか?間違いがありますか?読みにくいですか?みんなで 修正 していきましょう! (手順はこちら)
この項目はあなたにとって参考にならない項目ですか?もしかしたらLSL Wikiの関連した項目が参考になるかもしれません。