gpt4 book ai didi

c++ - 使用 std::random 创建全范围的随机 float

转载 作者:太空狗 更新时间:2023-10-29 21:00:09 25 4
gpt4 key购买 nike

我正在尝试使用来自所有可表示正float 范围内的随机数来测试我创建的数学类,但我发现我的使用似乎有问题std::random。这个程序

#include <random>
#include <iostream>
#include <functional>

template <typename T>
class Rand {
public:
Rand(T lo=std::numeric_limits<T>::min(),
T hi=std::numeric_limits<T>::max()) :
r(bind(std::uniform_real_distribution<>(lo, hi),std::mt19937_64{})) {}
T operator()() const { return r(); }
private:
std::function<T()> r;
};

int main()
{
Rand<float> f{};
const int samples = 1000000;
float min = std::numeric_limits<float>::max();
float max = std::numeric_limits<float>::min();
std::cout << "range min = " << max
<< ", max = " << min << '\n';
for (int i=0; i < samples; ++i) {
float r = f();
if (r < min) min = r;
if (r > max) max = r;
}
std::cout << "for n = " << samples
<< "\nsample min = " << min
<< ", max = " << max << std::endl;
}

产生这个输出

range min = 1.17549e-38, max = 3.40282e+38
for n = 1000000
sample min = 8.14884e+31, max = 3.40281e+38

显然,范围极度偏向于较大的数字。如何生成具有均匀分布的所需范围的 float

最佳答案

除了您打印出的统计数据外,我还计算了 this distribution 的理论和实际均值、方差、偏度和峰度。 .这是我的代码和结果:

#include <random>
#include <iostream>
#include <functional>
#include <vector>
#include <numeric>
#include <cmath>

template <typename T>
class Rand {
public:
Rand(T lo=std::numeric_limits<T>::min(),
T hi=std::numeric_limits<T>::max()) :
r(bind(std::uniform_real_distribution<>(lo, hi),std::mt19937_64{})) {}
T operator()() const { return r(); }
private:
std::function<T()> r;
};

template <class T>
inline
T
sqr(T x)
{
return x * x;
}

int main()
{
Rand<float> f{};
const int samples = 1000000;
float min = std::numeric_limits<float>::max();
float max = std::numeric_limits<float>::min();
std::vector<float> u;
std::cout << "range min = " << max
<< ", max = " << min << '\n';
for (int i=0; i < samples; ++i) {
float r = f();
if (r < min) min = r;
if (r > max) max = r;
u.push_back(r);
}
std::cout << "for n = " << samples
<< "\nsample min = " << min
<< ", max = " << max << std::endl;
double mean = std::accumulate(u.begin(), u.end(),
double(0)) / u.size();
double var = 0;
double skew = 0;
double kurtosis = 0;
for (int i = 0; i < u.size(); ++i)
{
double d = (u[i] - mean);
double d2 = sqr(d);
var += d2;
skew += d * d2;
kurtosis += d2 * d2;
}
var /= u.size();
double dev = std::sqrt(var);
skew /= u.size() * dev * var;
kurtosis /= u.size() * var * var;
kurtosis -= 3;
double x_mean = ((double)min + max) / 2;
double x_var = sqr((double)max - min) / 12;
double x_skew = 0;
double x_kurtosis = -6./5;
std::cout << std::scientific << '\n';
std::cout << " expected actual\n";
std::cout << "mean " << x_mean << " " << mean << "\n";
std::cout << "variance " << x_var << " " << var << "\n";
std::cout << "skew " << x_skew << " " << skew << "\n";
std::cout << "kurtosis " << x_kurtosis << " " << kurtosis << "\n";
}

结果如下:

range min = 1.17549e-38, max = 3.40282e+38
for n = 1000000
sample min = 8.14884e+31, max = 3.40281e+38

expected actual
mean 1.701407e+38 1.700724e+38
variance 9.649275e+75 9.645774e+75
skew 0.000000e+00 7.401975e-04
kurtosis -1.200000e+00 -1.199432e+00

我觉得一切都很好。

关于c++ - 使用 std::random 创建全范围的随机 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22895130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com