2011-06-24 15 views
2

これは既に議論されている場合は私を許してください。boost :: randomとboost:uniform_realはfloatではなくdoubleで動作しますか?

template <typename N> N getRandom(int min, int max) 
{ 
    timeval t; 
    gettimeofday(&t,NULL); 
    boost::mt19937 seed((int)t.tv_sec); 
    boost::uniform_int<> dist(min, max); 
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > random(seed, dist); 
    return random(); 
} 
//! partial specialization for real numbers 
template <typename N> N getRandom(N min, N max) 
{ 
    timeval t; 
    gettimeofday(&t,NULL); 
    boost::mt19937 seed((int)t.tv_sec); 
    boost::uniform_real<> dist(min,max); 
    boost::variate_generator<boost::mt19937&, boost::uniform_real<> > random(seed,dist); 
    return random(); 
} 

は今、私はint型、floatとdouble型を持つ関数をテストしてみた:私は:: uniform_int後押しと後押し:: uniform_realは、テンプレート引数に依存し、同じ型を返す必要があります使用するテンプレート機能を持っています。 intでうまく動作し、doubleでうまく動作しますが、浮動小数点数では機能しません。 floatをint型に変換するか、キャストに問題があるかのようです。理由は、私がそうしているからです。

float y = getRandom<float>(0.0,5.0); 

私はいつもintバックを取得します。 しかし、私が言ったように、それは倍で動作します。 私が間違っているか紛失していることがありますか? ありがとうございました!

+1

アレックス、あなたはいけませんこのように乱数を生成する。あなたは、関数への呼び出しのたびにあなたの種子を再生成しています。つまり、良いPRNGがあなたに与える素晴らしい保証をすべて失うことになります。あなたが生成している数字は、実際には「非ランダム」かもしれません。 – Richard

+0

@リチャードあなたはこれを観察した最初の人です!私はこの質問に約2年前に尋ねましたが、誰も気付いていませんでした。そして、はい、あなたは絶対に正しいです、私はこのようにPRNGを台無しにしています。私はそれ以来、私は適切なPRNGが必要なときは常にメルセンヌツイスターを使用してきました。それを言及してくれてありがとう:) –

答えて

7

引数は0.0,5.0は倍数であり、浮動小数点数ではありません。作る彼らが浮かぶ:

float y = getRandom<float>(0.0f,5.0f); 
+0

ありがとう、私はそれを知らなかった参照してください。 –

5

が本当にそれ自体があなたの質問に対処しますが、解決策ではありません:

右の配信タイプを取得する特性クラスを使用しないのはなぜ?そのセットで

template<class T> 
struct distribution 
{ // general case, assuming T is of integral type 
    typedef boost::uniform_int<> type; 
}; 

template<> 
struct distribution<float> 
{ // float case 
    typedef boost::uniform_real<> type; 
}; 

template<> 
struct distribution<double> 
{ // double case 
    typedef boost::uniform_real<> type; 
}; 

、あなたは1つの一般的な機能持つことができます:あなたも型特性とMPLとの定型的なコードを書くことを避けることができ

template <typename N> N getRandom(N min, N max) 
{ 
    typedef typename distribution<N>::type distro_type; 

    timeval t; 
    gettimeofday(&t,NULL); 
    boost::mt19937 seed((int)t.tv_sec); 
    distro_type dist(min,max); 
    boost::variate_generator<boost::mt19937&, distro_type > random(seed,dist); 
    return random(); 
}; 
+0

これはより洗練されたソリューションです。ありがとうございます –

+0

このコードは使用しないでください。それは本質的にPRNGの目的を破るすべての呼び出しで種を再生成します。 – Richard

+2

@リチャード:OPの問題を解決するために私を許してください - 正しいディストリビューションを選んでください。あなたは本当にこれがdownvoteの価値があると思いますか?この答えは「役に立たない」ですか? – Xeo

7

を:

template <typename N> 
N getRandom(N min, N max) 
{ 
    typedef typename boost::mpl::if_< 
    boost::is_floating_point<N>, // if we have a floating point type 
    boost::uniform_real<>,  // use this, or 
    boost::uniform_int<>   // else use this one 
    >::type distro_type; 

    timeval t; 
    gettimeofday(&t,NULL); 
    boost::mt19937 seed((int)t.tv_sec); 
    distro_type dist(min,max); 
    boost::variate_generator<boost::mt19937&, distro_type > random(seed,dist); 
    return random(); 
}; 
+1

このコードは使用しないでください。それは本質的にPRNGの目的を破るすべての呼び出しで種を再生成します。 – Richard

関連する問題