C ++随机浮点数生成
如何在C ++中生成随机的浮点数?
我想我可以把整数兰德分成几个等级,这足够吗?
rand()
可用于在C ++中生成伪随机数。 结合RAND_MAX
和一些小数学运算,您可以根据您选择的任意间隔生成随机数。 这对于学习目的和玩具程序已经足够了。 如果您需要正态分布的真正随机数字,则需要采用更高级的方法。
这将生成一个从0.0到1.0的数字。
float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
这将产生一个从0.0到某个任意float
, X
:
float r2 = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/X));
这将从一些任意的LO
生成一个数字到一些任意的HI
:
float r3 = LO + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(HI-LO)));
请注意,如果您需要真正的随机数, rand()
函数通常是不够的。
在调用rand()
之前,你必须首先通过调用srand()
“随机生成”随机数生成器。 这应该在程序运行期间执行一次 - 不是每次调用rand()
都执行一次。 这通常是这样做的:
srand (static_cast <unsigned> (time(0)));
为了调用rand
或srand
你必须#include <cstdlib>
。
为了调用time
,你必须#include <ctime>
。
C ++ 11为您提供了许多random
的新选项。 关于这个主题的标准论文将是N3551,C ++ 11中的随机数生成
要了解为什么使用rand()
可能会有问题,请参阅2013年GoingNative活动期间提供的Stephan T. Lavavej提供的rand()有害演示材料。 幻灯片在评论中,但这里是直接链接。
我还介绍了boost
以及使用rand
因为遗留代码可能仍需要它的支持。
下面的例子是从cppreference站点中提炼出来的,并使用std :: mersenne_twister_engine引擎和std :: uniform_real_distribution,它在[0,10)
间隔内生成数字,其他引擎和分发版本被注释掉(现场直播):
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
int main()
{
std::random_device rd;
//
// Engines
//
std::mt19937 e2(rd());
//std::knuth_b e2(rd());
//std::default_random_engine e2(rd()) ;
//
// Distribtuions
//
std::uniform_real_distribution<> dist(0, 10);
//std::normal_distribution<> dist(2, 2);
//std::student_t_distribution<> dist(5);
//std::poisson_distribution<> dist(2);
//std::extreme_value_distribution<> dist(0,2);
std::map<int, int> hist;
for (int n = 0; n < 10000; ++n) {
++hist[std::floor(dist(e2))];
}
for (auto p : hist) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/200, '*') << 'n';
}
}
输出将类似于以下内容:
0 ****
1 ****
2 ****
3 ****
4 *****
5 ****
6 *****
7 ****
8 *****
9 ****
输出将根据您选择的分布而变化,所以如果我们决定以std :: normal_distribution的值为2
来表示mean和stddev,例如dist(2, 2)
则输出将与此类似(请参阅生活):
-6
-5
-4
-3
-2 **
-1 ****
0 *******
1 *********
2 *********
3 *******
4 ****
5 **
6
7
8
9
以下是N3551
提供的一些代码的修改版本(请参阅实况):
#include <algorithm>
#include <array>
#include <iostream>
#include <random>
std::default_random_engine & global_urng( )
{
static std::default_random_engine u{};
return u ;
}
void randomize( )
{
static std::random_device rd{};
global_urng().seed( rd() );
}
int main( )
{
// Manufacture a deck of cards:
using card = int;
std::array<card,52> deck{};
std::iota(deck.begin(), deck.end(), 0);
randomize( ) ;
std::shuffle(deck.begin(), deck.end(), global_urng());
// Display each card in the shuffled deck:
auto suit = []( card c ) { return "SHDC"[c / 13]; };
auto rank = []( card c ) { return "AKQJT98765432"[c % 13]; };
for( card c : deck )
std::cout << ' ' << rank(c) << suit(c);
std::cout << std::endl;
}
结果看起来类似于:
5H 5S AS 9S 4D 6H TH 6D KH 2S QS 9H 8H 3D KC TD 7H 2D KS 3C TC 7D 4C QH QC QD JD AH JC AC KD 9D 5C 2H 4H 9C 8C JH 5D 4S 7C AD 3S 8S TS 2C 8D 3H 6C JS 7S 6S
促进
当然Boost.Random总是一个选项,在这里我使用boost :: random :: uniform_real_distribution:
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_real_distribution.hpp>
int main()
{
boost::random::mt19937 gen;
boost::random::uniform_real_distribution<> dist(0, 10);
std::map<int, int> hist;
for (int n = 0; n < 10000; ++n) {
++hist[std::floor(dist(gen))];
}
for (auto p : hist) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/200, '*') << 'n';
}
}
RAND()
如果你必须使用rand()
那么我们可以去C FAQ的一个指南如何生成浮点随机数? ,它基本上给出了一个类似于这样的例子来生成一个区间[0,1)
:
#include <stdlib.h>
double randZeroToOne()
{
return rand() / (RAND_MAX + 1.);
}
并在[M,N)
范围内生成一个随机数:
double randMToN(double M, double N)
{
return M + (rand() / ( RAND_MAX / (N-M) ) ) ;
}
看看Boost.Random。 你可以做这样的事情:
float gen_random_float(float min, float max)
{
boost::mt19937 rng;
boost::uniform_real<float> u(min, max);
boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > gen(rng, u);
return gen();
}
游玩一下,你可能会更好地传递相同的mt19937对象,而不是每次都创建一个新对象,但希望你能明白。
链接地址: http://www.djcxy.com/p/96727.html上一篇: C++ random float number generation
下一篇: Vert.x: correctly stream to http response in case of closed client connection