2016-06-15 44 views
1

私は倍精度で数値を提供するメルセンヌツイスターの実装を使用しています。単精度への倍精度の丸め:上限の強制

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/FORTRAN/fortran.html(剛多田により、Fortran 77の中に実装、私はgenrand_real2を使用しています)

しかし、私のアプリケーションのニーズ、異なる精度、単精度の乱数で数を乗算しながら、警告を回避するためです。 だから、私は2つのデータ型間の変換に小さな関数を書いた:

function genrand_real() 

    real genrand_real 
    real*8 genrand_real2 

    genrand_real = real(genrand_real2()) 

    return 
    end 

私は私が働いているコードと一致するように現実と実際の* 8を使用しています。 これはほとんどの場合(実際には本当の()がどれくらい速いか分からないだけでなく)、RNGの上限を変更します。変換によって[0,1]が[0 、1]。私はそれに問題があるまでそれについて考えたことはありません。

私の質問は、どのように効率的な方法で上限を保証することができますか、私は単精度実数を提供するgenrand_real2(元のもの)に似た関数を書くことができます。私の推測では、私が唯一の除数4294967296.d0を交換する必要があるが、あなたが投稿機能は、乱数を生成しません

function genrand_real2() 

    double precision genrand_real2,r 
    integer genrand_int32 
    r=dble(genrand_int32()) 
    if(r.lt.0.d0)r=r+2.d0**32 
    genrand_real2=r/4294967296.d0 

    return 
    end 

答えて

1

た数で、私は知らない、それだけに(genrand_int32()から)整数の乱数を制限します2^32(ちょうど4294967296)で割るか、またはintが負の場合は最初に2^32を足して、[0,1]の間隔を置いてください。 2^32は標準整数が保持できる値の数であり、1つの半分の負数、1つの半分の正数です(正の端に1がありません)。したがって、genrand_int32()関数から来ます。

-10から10までの数字があり、間隔[0,1]に制限したいとします。最も簡単な解決策は、負の数に20を加算することです(正の滞在0-10と負は10-20になります)。 これはまさに関数が行っていることです。ちょうど10の代わりに2^31を使用します。

なぜあなたの関数の間隔が[0、1]であるのか疑問に思っている場合: 番号0にもスポットが必要で、ビット表現には2^32個の数値しか格納できないので、2^31負の値と2^31の正の値と0です。解決策は、値+ 2^31(最高の正の値)を除外することで、結果として1があなたの区間から除外されます。

だからダウンシングルprecissionに全部持って来るために:彼らは、整数、実数ではないに関連しているため

function genrand_real2() 

real genrand_real2,r 
integer genrand_int32 
r=real(genrand_int32()) 
if(r.lt.0)r=r+2**32 
genrand_real2=r/4294967296 

return 
end 

をマジックナンバーは、同じ滞在する必要があります。

編集は: あなたはすでにそれを自分で言ったので、私はちょうど他の人のために繰り返しています:ポータビリティのために、精度を指定せずにデフォルトのタイプを使用することは技術的には良いアイデアではありません。したがって、sp = selected_real_kind(6, 37)(単精度の場合はsp)を指定してから、real(kind=sp)...2.0_spなどとします。 しかし、これは学問的な点です。

+0

ありがとうございます! あなたは私の問題を解決するだけでなく、私のプログラムをもっと速くしました。 mt19937 経過:11.5120001、ユーザ:11.5120001、sys:0。00000000 mt19937単精度 経過:4.83599997、ユーザー:4.83599997、sys:0.00000000 –

+0

よろしくお願いいたします。これは単純に高精度を使用しないという効果です。欠点はありますが、http://stackoverflow.com/a/17951021/(それはC#用ですが、コンセプトは同じです)を参照してください。しかし、プログラムの残りの部分が単精度の実数であれば、それは重要ではありません。 – StefanS

+0

もう一度、あなたの助けをありがとう、 "その男"であることについて申し訳ありませんが、私は質問をフォローアップがあります:http://stackoverflow.com/questions/37859027/upper-bound-of-random-number-generator –