2010-04-24 407 views
62

如何在C++中的兩個雙精度值之間生成隨機數,這些數字應該看起來像xxxxx,yyyyy。在C++中生成隨機雙數

+5

「這些數字應該看起來像xxxxx,yy YYY」。如何生成隨機雙打,以及如何將雙打格式化爲字符串,都是完全不同的問題。 – 2010-04-24 13:09:07

+0

然後想一想:或者生成均勻分佈的*雙*和生成均勻分佈的*小數*有點不同,儘管是相關的任務。 – 2010-04-24 13:24:39

+0

生成均勻分佈的整數與小數點問題更密切相關。 – Potatoswatter 2010-04-24 19:56:03

回答

89

下面是如何

double fRand(double fMin, double fMax) 
{ 
    double f = (double)rand()/RAND_MAX; 
    return fMin + f * (fMax - fMin); 
} 

記住調用srand()函數,每個程序啓動時正確的種子。

+2

排除最大值(通常完成):將+1加到RAND_MAX – KillianDS 2010-04-24 13:12:13

+9

如果您將1加到RAND_MAX,請謹慎操作,因爲它可能等於INT_MAX。 'double f = rand()/(RAND_MAX + 1.0);' – 2010-04-24 13:22:55

+7

請注意,它的隨機性可能受到限制。範圍xxxxx,yyyyy表示10個十進制數字。有很多系統的RAND_MAX小於10^10。這意味着該範圍內的某些數字具有'p(xxxxx,yyyyy)== 0.0' – MSalters 2010-04-26 12:46:46

0

是這樣的:

#include <iostream> 
#include <time.h> 

using namespace std; 

int main() 
{ 
    const long max_rand = 1000000L; 
    double x1 = 12.33, x2 = 34.123, x; 

    srandom(time(NULL)); 

    x = x1 + (x2 - x1) * (random() % max_rand)/max_rand; 

    cout << x1 << " <= " << x << " <= " << x2 << endl; 

    return 0; 
} 
+1

「(random()%max_rand)」=「random() 「(即3%7 = 3)。這將是一個浪費的處理步驟。 – Zak 2012-01-25 21:53:12

62

這種解決方案需要C++ 11(或TR1)。

#include <random> 

int main() 
{ 
    double lower_bound = 0; 
    double upper_bound = 10000; 
    std::uniform_real_distribution<double> unif(lower_bound,upper_bound); 
    std::default_random_engine re; 
    double a_random_double = unif(re); 

    return 0; 
} 

欲瞭解更多詳情,請參閱約翰D.庫克的"Random number generation using C++ TR1"

另請參見Stroustrup的"Random number generation"

+6

你可能想用更新的[cppreference](http://en.cppreference.com/w/cpp/numeric/random)文件來更新它,這很好。 – 2013-07-23 03:07:55

7

如果準確性是一個問題,那麼您可以通過隨機化重要比特來創建具有更精細分級的隨機數。我們假設我們想要在0.0到1000.0之間加倍。

在MSVC(12/Win32)上RAND_MAX例如是32767。

如果使用普通rand()/RAND_MAX方案的差距會那麼大

1.0/32767.0 * (1000.0 - 0.0) = 0.0305 ... 

在IEE的情況下,754個變量(53顯著位)和53位隨機儘可能小的隨機化空白,爲0〜 1000的問題將是

2^-53 * (1000.0 - 0.0) = 1.110e-13 

因此顯着降低。

不利的一面是需要4個rand()調用才能獲得隨機化的整數(假設是15位的RNG)。

double random_range (double const range_min, double const range_max) 
{ 
    static unsigned long long const mant_mask53(9007199254740991); 
    static double const i_to_d53(1.0/9007199254740992.0); 
    unsigned long long const r((unsigned long long(rand()) | (unsigned long long(rand()) << 15) | (unsigned long long(rand()) << 30) | (unsigned long long(rand()) << 45)) & mant_mask53); 
    return range_min + i_to_d53*double(r)*(range_max-range_min); 
} 

如果尾數或RNG的比特數是未知的各自的值需要在函數內獲得。

#include <limits> 
using namespace std; 
double random_range_p (double const range_min, double const range_max) 
{ 
    static unsigned long long const num_mant_bits(numeric_limits<double>::digits), ll_one(1), 
    mant_limit(ll_one << num_mant_bits); 
    static double const i_to_d(1.0/double(mant_limit)); 
    static size_t num_rand_calls, rng_bits; 
    if (num_rand_calls == 0 || rng_bits == 0) 
    { 
    size_t const rand_max(RAND_MAX), one(1); 
    while (rand_max > (one << rng_bits)) 
    { 
     ++rng_bits; 
    } 
    num_rand_calls = size_t(ceil(double(num_mant_bits)/double(rng_bits))); 
    } 
    unsigned long long r(0); 
    for (size_t i=0; i<num_rand_calls; ++i) 
    { 
    r |= (unsigned long long(rand()) << (i*rng_bits)); 
    } 
    r = r & (mant_limit-ll_one); 
    return range_min + i_to_d*double(r)*(range_max-range_min); 
} 

注:我不知道位無符號很長很長(64位)的數量是否比雙尾數位的所有平臺上或沒有編號(53位的IEE 754)更大。 如果不是這種情況,那麼包括像if (sizeof(unsigned long long)*8 > num_mant_bits) ...這樣的檢查可能是「聰明的」。

2

這段代碼直接來自Stroustrup的The C++ Programming Language (4th Edition),§40。7;它需要C++ 11:

#include <functional> 
#include <random> 

class Rand_double 
{ 
public: 
    Rand_double(double low, double high) 
    :r(std::bind(std::uniform_real_distribution<>(low,high),std::default_random_engine())){} 

    double operator()(){ return r(); } 

private: 
    std::function<double()> r; 
}; 

#include <iostream>  
int main() { 
    // create the random number generator: 
    Rand_double rd{0,0.5}; 

    // print 10 random number between 0 and 0.5 
    for (int i=0;i<10;++i){ 
     std::cout << rd() << ' '; 
    } 
    return 0; 
} 
1

這應該是高性能,線程安全的,並足夠靈活的多種用途:

#include <random> 
#include <iostream> 

template<typename Numeric, typename Generator = std::mt19937> 
Numeric random(Numeric from, Numeric to) 
{ 
    thread_local static Generator gen(std::random_device{}()); 

    using dist_type = typename std::conditional 
    < 
     std::is_integral<Numeric>::value 
     , std::uniform_int_distribution<Numeric> 
     , std::uniform_real_distribution<Numeric> 
    >::type; 

    thread_local static dist_type dist; 

    return dist(gen, typename dist_type::param_type{from, to}); 
} 

int main(int, char*[]) 
{ 
    for(auto i = 0U; i < 20; ++i) 
     std::cout << random<double>(0.0, 0.3) << '\n'; 
} 
0
  • 這是C++
#include "stdafx.h" 
#include "iostream" 
#include "ctime" 

using namespace std; 

double getRandom(double min, double max) 
{ 
    double before = rand() % (int)max + (int)min; 
    double after = (double)rand()/RAND_MAX; 
    double result = before + after; 
    if (result < min || result > max) { 
     result = getRandom(min, max); 
    } 
    return result; 
} 

int main() 
{ 
    srand (time(NULL)); 
    for (int i = 0; i < 100; i++) { 
     double number = getRandom(-1.57079632679, 1.57079632679); 
     cout << number << endl; 
    } 
    system("pause"); 
}