rep*_*vsd 106
这是如何做
double fRand(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
Run Code Online (Sandbox Code Playgroud)
每次程序启动时,请记住使用适当的种子调用srand().
[编辑]这个答案已经过时了,因为C++得到了它的原生非基于C的随机库(参见Alessandro Jacopsons回答)但是,这仍然适用于C
Ale*_*son 87
该解决方案需要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;
}
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅John D. Cook的"使用C++ TR1生成随机数".
另请参阅Stroustrup的"随机数生成".
如果精度是一个问题,你可以通过随机化有效位创建更精细的随机数.假设我们想要一个介于0.0和1000.0之间的双精度.
在MSVC(12/Win32)上,RAND_MAX例如是32767.
如果你使用通用rand()/RAND_MAX方案,你的差距就会大到
1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...
Run Code Online (Sandbox Code Playgroud)
在IEE 754双变量(53个有效位)和53位随机化的情况下,0到1000问题的最小可能随机化间隙将是
2^-53 * (1000.0 - 0.0) = 1.110e-13
Run Code Online (Sandbox Code Playgroud)
因此显着降低.
缺点是需要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);
}
Run Code Online (Sandbox Code Playgroud)
如果尾数或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);
}
Run Code Online (Sandbox Code Playgroud)
注意:我不知道无符号长long(64位)的位数是否大于所有平台上的双尾数位(IEE 754为53位).if (sizeof(unsigned long long)*8 > num_mant_bits) ...如果不是这样的话,包括支票可能是"聪明的" .
对于许多用途,这应该是高性能的,线程安全的并且足够灵活:
#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';
}
Run Code Online (Sandbox Code Playgroud)
此片段直接来自 Stroustrup 的《C++ 编程语言》(第 4 版) \xc2\xa740.7;它需要 C++11:
\n\n#include <functional>\n#include <random>\n\nclass Rand_double\n{\npublic:\n Rand_double(double low, double high)\n :r(std::bind(std::uniform_real_distribution<>(low,high),std::default_random_engine())){}\n\n double operator()(){ return r(); }\n\nprivate:\n std::function<double()> r;\n};\n\n#include <iostream> \nint main() {\n // create the random number generator:\n Rand_double rd{0,0.5};\n\n // print 10 random number between 0 and 0.5\n for (int i=0;i<10;++i){\n std::cout << rd() << \' \';\n }\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n