2013-04-25 6 views
9

C++ 11 std :: uniform_real_distribution (-1, 1) gibt Zahlen im Bereich [-1,1).std :: uniform_real_distribution included range

Wie erhalten Sie eine gleichmäßige reale Verteilung im Bereich [-1,1]?

Praktisch ist es wahrscheinlich egal, aber logisch versuche ich einen Wert im inklusiven Bereich zu wählen.

Antwort

14

Dies ist einfacher zu denken, wenn Sie mit Ganzzahlen beginnen. Wenn Sie [-1, 1) übergeben, würden Sie erwarten, -1, 0 zu erhalten. Da Sie 1 einschließen möchten, übergeben Sie [-1, (1 + 1)) oder [-1, 2). Jetzt erhalten Sie -1, 0, 1.

Sie wollen das Gleiche tun, aber mit Doppel:

Borrowing von 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; 
} 

(Siehe den Code ausführen here)

Das heißt, finden die nächstgrößere Doppel Wert nach dem gewünschten Wert und übergeben Sie diesen stattdessen als Endwert.

+1

Wunderbar, danke. VS2012 scheint diese Funktion nicht zu haben, aber zum Glück hat Boost es in [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

Die Standard-Fließkomma-Verteilungen bieten keine Genauigkeit bis zur letzten Genauigkeitsziffer, sondern leiden an Rundungsfehlern, die bedeuten, dass es nicht angemessen ist, sie auf diese Weise zu verwenden. – bames53

1

Leider erlauben die tatsächlichen Implementierungen der Gleitkomma-Verteilungen Sie nicht, so genau zu sein. Zum Beispiel soll uniform_real_distribution<float> Werte in einem gegebenen halben Bereich erzeugen, aber aufgrund von Rundungsproblemen kann es tatsächlich Werte in einem inklusiven Bereich stattdessen erzeugen.

Here's ein Beispiel für das Problem mit generate_cannonical, und ähnliche Probleme auftreten, mit den anderen real_distributions.