C++ 在c+中生成随机双精度数+; 这里是 double fRand(double fMin, double fMax) { double f = (double)rand() / RAND_MAX; return fMin + f * (fMax - fMin); }

C++ 在c+中生成随机双精度数+; 这里是 double fRand(double fMin, double fMax) { double f = (double)rand() / RAND_MAX; return fMin + f * (fMax - fMin); },c++,random,C++,Random,请记住,每次程序启动时都要使用适当的种子调用srand() [编辑] 这个回答是过时的,因为C++获得了它的本地非基于C的随机库(见Alessandro Jacopsons回答) 但是,这仍然适用于C类似的情况: #include <iostream> #include <time.h> using namespace std; int main() { const long max_rand = 1000000L; double x1 = 12.33

请记住,每次程序启动时都要使用适当的种子调用srand()

[编辑] 这个回答是过时的,因为C++获得了它的本地非基于C的随机库(见Alessandro Jacopsons回答) 但是,这仍然适用于C

类似的情况:

#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;
}
#包括
#包括
使用名称空间std;
int main()
{
const long max_rand=1000000升;
双x1=12.33,x2=34.123,x;
srandom(时间(空));
x=x1+(x2-x1)*(随机)(%max\u rand)/max\u rand;

cout此解决方案需要C++11(或TR1)

#包括
int main()
{
双下界=0;
双上界=10000;
一致实分布unif(下界,上界);
std::默认\u随机\u引擎re;
双a_随机_双=unif(re);
返回0;
}
有关更多详细信息,请参阅约翰·D·库克的


另请参见Stroustrup。

如果此处存在精度问题,您可以通过将有效位随机化来创建具有更精细刻度的随机数。 假设我们想要一个介于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)

双随机范围(双常数范围最小值,双常数范围最大值)
{
静态无符号长常量mant_mask53(9007199254740991);
静态双常数i_至d53(1.0/9007199254740992.0);

unsigned long long const r((unsigned long(rand())|)(unsigned long(rand())此代码段直接来自Stroustrup的§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;
}
#包括
#包括
类随机双
{
公众:
双随机(双低双高)
:r(std::bind(std::uniform\u real\u distribution(low,high),std::default\u random\u engine()){}
双运算符()({return r();}
私人:
std::函数r;
};
#包括
int main(){
//创建随机数生成器:
Rand_double rd{0,0.5};
//打印10个介于0和0.5之间的随机数

对于(int i=0;i这应该是性能良好、线程安全且足够灵活的,可用于多种用途:

#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';
}
#包括
#包括
模板
数字随机(数字从、数字到)
{
线程_本地静态生成器gen(std::random_设备{}());
使用dist_type=typename std::conditional
<
std::is_integral::value
,std::均匀分布
,std::均匀实分布
>::类型;
螺纹\本地静态距离\类型距离;
返回dist(gen,typename dist_type::param_type{from,to});
}
int main(int,char*[])
{
用于(自动i=0U;i<20;++i)

对于生成随机数,我们可以使用其他朋友告诉我们的方法。我想在这里补充一个非常重要的观点

其他人告诉我们的代码是:

//I have made this as a function that returns the random double value, just copy this
// if you want
double random(){
    return (double)rand() / RAND_MAX; // for generating random points between 0 to 1
}
//now suppose I want any random value between two numbers min and max then I can use this as :
int mynum = min + (max-min)*random();
但这段代码的问题是它有偏差,我的意思是它的值在0和1之间不相等。 此图显示了返回的值如何更偏向中心(即接近值1)。为了避免这种情况,我们应该选择以下代码:

double random(){
        return sqrt((double)rand() / RAND_MAX); // for generating random points between 0 to 1
    }
选择平方根函数的原因

选择sqrt()而不是cbrt()等任何其他函数的原因使其偏向外端的方法是,在上面提到的第一种方法中,生成的点与R^2成比例,因为我们的随机数与R成比例,因此使圆的点总面积与R^2成比例,这使它们更集中于中心。使我们的随机数与sqrt(R)成比例将使在圆的所有区域上生成的点与R成比例,这将使所有点在整个圆上均匀生成

请注意,应用sqrt(介于[0,1]之间的点)后,结果将是一个大于原始random()的值,从而使其更偏向外端。这将使点在整个圆上均匀生成


我想感谢@ Err91在

上分享这些有用的信息。很多这样的解决方案已经很多,很多都很优雅。我只是想把另外一个列表添加到列表中。我直接从“现代C++编程食谱,第二版”中引用。在随机数生成器的章节中,有一些。强调正确初始化伪随机数生成器的重要性。它补充说,Mersenne twister引擎倾向于重复生成某些值,而不包含其他值,因此不会生成均匀分布的数,更像是二项式或泊松分布。片段I am Iincluding经过初始化生成器的步骤,以生成具有真实均匀分布的伪随机数

auto generate_random_double(double lb, double ub)//lb= lowerbound, ub = upperbound
{
    //produce random #'s to be used as seeding values
    std::random_device rd{};

    //Generate random data for all the internal bits of the engine
    std::array<double, std::mt19937::state_size> seed_data{};
    ranges::generate(seed_data,std::ref(rd));
    
    //Create an std::seed_seq object from the pseudo random data 
    std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
    
    //Create an engine object and initialize the bits representing the internal      
    //state of the engine; form example an mt19937 has 19937 bits
    auto eng = std::mt19937{ seq };

    //Create object based on the approprieat distribution based on application   
    //requirments 
    const auto randDouble = std::uniform_real_distribution<>{ lb,ub };

    //return object seeded with the previously initialized object
    return randDouble(eng);

}//end method generate_random_double
auto generate\u random\u double(双磅,双磅)//lb=lowerbound,ub=upperbound
{
//生成用作种子值的随机#
std::随机_设备rd{};
//为引擎的所有内部位生成随机数据
std::数组种子_数据{};
范围::生成(种子_数据,标准::参考(rd));
//从伪随机数据创建std::seed_seq对象
std::seed_seq seq(std::begin(seed_数据),std::end(seed_数据));
//创建引擎对象并初始化表示内部
//发动机状态;例如mt19937具有19937位
auto eng=std::mt19937{seq};
//基于基于应用程序的适当分布创建对象
//要求
//I have made this as a function that returns the random double value, just copy this
// if you want
double random(){
    return (double)rand() / RAND_MAX; // for generating random points between 0 to 1
}
//now suppose I want any random value between two numbers min and max then I can use this as :
int mynum = min + (max-min)*random();
double random(){
        return sqrt((double)rand() / RAND_MAX); // for generating random points between 0 to 1
    }
auto generate_random_double(double lb, double ub)//lb= lowerbound, ub = upperbound
{
    //produce random #'s to be used as seeding values
    std::random_device rd{};

    //Generate random data for all the internal bits of the engine
    std::array<double, std::mt19937::state_size> seed_data{};
    ranges::generate(seed_data,std::ref(rd));
    
    //Create an std::seed_seq object from the pseudo random data 
    std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
    
    //Create an engine object and initialize the bits representing the internal      
    //state of the engine; form example an mt19937 has 19937 bits
    auto eng = std::mt19937{ seq };

    //Create object based on the approprieat distribution based on application   
    //requirments 
    const auto randDouble = std::uniform_real_distribution<>{ lb,ub };

    //return object seeded with the previously initialized object
    return randDouble(eng);

}//end method generate_random_double