2013-04-25 9 views
9

C++ 11 std :: uniform_real_distribution(-1、1)は[-1,1]の範囲の数値を返します。std :: uniform_real_distribution包含範囲

[-1,1]の範囲で均一な実際の分布をどのように取得しますか?

これはおそらく問題ではありませんが、論理的には包括的な範囲の値を選択しようとしています。

答えて

14

これは、整数を見ることから始めるのが簡単だと思います。 [-1、1]に合格すると、-1, 0が得られます。 1を含めるので、[-1、(1 + 1))、または[-1、2]を渡します。今度は-1, 0, 1になります。あなたが同じことをしたい

が、ダブルスで:this answerから

借入:

#include <cfloat> // DBL_MAX 
#include <cmath> // std::nextafter 
#include <random> 
#include <iostream> 

int main() 
{ 
    const double start = -1.0; 
    const double stop = 1.0; 

    std::random_device rd; 
    std::mt19937 gen(rd()); 

    // Note: uniform_real_distribution does [start, stop), 
    // but we want to do [start, stop]. 
    // Pass the next largest value instead. 
    std::uniform_real_distribution<> dis(start, std::nextafter(stop, DBL_MAX)); 

    for (auto i = 0; i < 100; ++i) 
    { 
    std::cout << dis(gen) << "\n"; 
    } 
    std::cout << std::endl; 
} 

(コードの実行hereを参照してください)

ダブル次の最大を見つけること、ですあなたが望むものの後ろに値を置き、それを代わりに終わりの値として渡します。

+1

素晴らしいです、ありがとうございます。 VS2012はこの機能を持っていませんが、幸いなことに[math toolkit](http://www.boost.org/doc/libs/1_53_0/libs/math/doc/sf_and_dist/html/math_toolkit/utils/)にあります。 next_float/nextafter.html) –

+0

標準の浮動小数点分布は、精度の最後の桁まで精度を提供するのではなく、丸めの問題を抱えているため、このように使用しようとするのは適切ではありません。 – bames53

1

浮動小数点分布の実際の実装では、あまり正確ではありません。たとえば、uniform_real_distribution<float>は、指定された半分の範囲で値を生成すると仮定されていますが、丸めの問題により、実際には包括的な範囲の値が生成される可能性があります。

Here'sgenerate_cannonicalの問題の例であり、他のreal_distributionsでは同様の問題が発生します。