在 C++ 中生成随机双数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2704521/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
generate random double numbers in c++
提问by Radi
How to generate random numbers between two doubles in c++ , these numbers should look like xxxxx,yyyyy .
如何在 C++ 中的两个双打之间生成随机数,这些数字应该看起来像 xxxxx,yyyyy 。
回答by rep_movsd
Here's how
就是这样
double fRand(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
Remember to call srand() with a proper seed each time your program starts.
记住在每次程序启动时使用适当的种子调用 srand()。
[Edit] This answer is obsolete since C++ got it's native non-C based random library (see Alessandro Jacopsons answer) But, this still applies to C
[编辑] 这个答案已经过时了,因为 C++ 得到了它的原生非基于 C 的随机库(参见 Alessandro Jacopsons 的答案)但是,这仍然适用于 C
回答by Alessandro Jacopson
This solution requires C++11 (or TR1).
此解决方案需要 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;
}
For more details see John D. Cook's "Random number generation using C++ TR1".
有关更多详细信息,请参阅 John D. Cook 的“使用 C++ TR1 生成随机数”。
See also Stroustrup's "Random number generation".
另请参阅 Stroustrup 的“随机数生成”。
回答by Galik
This should be performant, thread-safe and flexible enough for many uses:
这应该是高性能、线程安全和足够灵活的,可以用于多种用途:
#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';
}
回答by Pixelchemist
If accuracy is an issue here you can create random numbers with a finer graduation by randomizing the significant bits. Let's assume we want to have a double between 0.0 and 1000.0.
如果此处存在准确性问题,您可以通过随机化有效位来创建具有更精细刻度的随机数。假设我们想要一个介于 0.0 和 1000.0 之间的双精度值。
On MSVC (12 / Win32) RAND_MAX is 32767 for example.
例如,在 MSVC (12 / Win32) 上 RAND_MAX 是 32767。
If you use the common rand()/RAND_MAX
scheme your gaps will be as large as
如果您使用通用rand()/RAND_MAX
方案,您的差距将与
1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...
In case of IEE 754 double variables (53 significant bits) and 53 bit randomization the smallest possible randomization gap for the 0 to 1000 problem will be
在 IEE 754 双变量(53 个有效位)和 53 位随机化的情况下,0 到 1000 问题的最小可能随机化差距将是
2^-53 * (1000.0 - 0.0) = 1.110e-13
and therefore significantly lower.
因此显着降低。
The downside is that 4 rand() calls will be needed to obtain the randomized integral number (assuming a 15 bit RNG).
缺点是需要 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);
}
If the number of bits for the mantissa or the RNG is unknown the respective values need to be obtained within the function.
如果尾数或 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);
}
Note: I don't know whether the number of bits for unsigned long long (64 bit) is greater than the number of double mantissa bits (53 bit for IEE 754) on all platforms or not.
It would probably be "smart" to include a check like if (sizeof(unsigned long long)*8 > num_mant_bits) ...
if this is not the case.
注意:我不知道所有平台上 unsigned long long(64 位)的位数是否大于双尾数位(IEE 754 为 53 位)的位数。if (sizeof(unsigned long long)*8 > num_mant_bits) ...
如果不是这种情况,包含一个检查可能是“聪明的” 。
回答by Alessandro Jacopson
This snippet is straight from Stroustrup's The C++ Programming Language (4th Edition), §40.7; it requires C++11:
这段代码直接来自 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;
}
回答by Oleg Razgulyaev
something like this:
像这样:
#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;
}