C ++随机浮点数生成

`rand()`可用于在C ++中生成伪随机数。 结合`RAND_MAX`和一些小math运算，您可以在您select的任意时间间隔内生成随机数。 这对于学习目的和玩具程序已经足够了。 如果你需要正态分布的真正的随机数，你需要采用更高级的方法。

` `float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);` `

` `float r2 = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/X));` `

` `float r3 = LO + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(HI-LO)));` `

` `srand (static_cast <unsigned> (time(0)));` `

C ++ 11为你提供了很多`random`的新选项。 关于这个主题的规范文件是N3551，C ++ 11中的随机数生成

` `#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 ****` `

` `-6 -5 -4 -3 -2 ** -1 **** 0 ******* 1 ********* 2 ********* 3 ******* 4 **** 5 ** 6 7 8 9` `

` `#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

` `#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（）

` `#include <stdlib.h> double randZeroToOne() { return rand() / (RAND_MAX + 1.); }` `

` `double randMToN(double M, double N) { return M + (rand() / ( RAND_MAX / (NM) ) ) ; }` `

` `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(); }` `

` `float rand_FloatRange(float a, float b) { return ((b - a) * ((float)rand() / RAND_MAX)) + a; }` `

` ` #include <iostream> #include <random> ... std::tr1::mt19937 eng; // a core engine class std::tr1::normal_distribution<float> dist; for (int i = 0; i < 10; ++i) std::cout << dist(eng) << std::endl;` `

` `float get_random() { static std::default_random_engine e; static std::uniform_real_distribution<> dis(0, 1); // rage 0 - 1 return dis(e); }` `

`float`放在`std::vector`这样的容器中是理想的：

` `int main() { std::vector<float> nums; for (int i{}; i != 5; ++i) // Generate 5 random floats nums.emplace_back(get_random()); for (const auto& i : nums) std::cout << i << " "; }` `

` `0.0518757 0.969106 0.0985112 0.0895674 0.895542` `

` `float r = (float)((rand() << 15 + rand()) & ((1 << 24) - 1)) / (1 << 24);` `

`drand48(3)`是POSIX的标准方式。 GLibC还提供了一个可重入版本`drand48_r(3)`

` `//Returns a random number in the range [0.0f, 1.0f). Every //bit of the mantissa is randomized. float rnd(void){ //Generate a random number in the range [0.5f, 1.0f). unsigned int ret = 0x3F000000 | (0x7FFFFF & ((rand() << 8) ^ rand())); unsigned short coinFlips; //If the coin is tails, return the number, otherwise //divide the random number by two by decrementing the //exponent and keep going. The exponent starts at 63. //Each loop represents 15 random bits, aka 'coin flips'. #define RND_INNER_LOOP() \ if( coinFlips & 1 ) break; \ coinFlips >>= 1; \ ret -= 0x800000 for(;;){ coinFlips = rand(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); //At this point, the exponent is 60, 45, 30, 15, or 0. //If the exponent is 0, then the number equals 0.0f. if( ! (ret & 0x3F800000) ) return 0.0f; RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP(); } return *((float *)(&ret)); }` `

` `float rand_float() { // returns a random value in the range [0.0-1.0) // start with a bit pattern equating to 1.0 uint32_t pattern = 0x3f800000; // get 23 bits of random integer uint32_t random23 = 0x7fffff & (rand() << 8 ^ rand()); // replace the mantissa, resulting in a number [1.0-2.0) pattern |= random23; // convert from int to float without undefined behavior assert(sizeof(float) == sizeof(uint32_t)); char buffer[sizeof(float)]; memcpy(buffer, &pattern, sizeof(float)); float f; memcpy(&f, buffer, sizeof(float)); return f - 1.0; }` `

|符号（1位）| e（8位）| f（23位）|

` `int tmp = rand(); float f = (float)*((float*)&tmp);` `

` `int tmp = rand(); float f = *((float*)&tmp); tmp = (unsigned int)f // note float to int conversion! tmp %= max_number; f -= tmp;` `

` `/** * Function generates a random float using the upper_bound float to determine * the upper bound for the exponent and for the fractional part. * @param min_exp sets the minimum number (closest to 0) to 1 * e^min_exp (min -127) * @param max_exp sets the maximum number to 2 * e^max_exp (max 126) * @param sign_flag if sign_flag = 0 the random number is always positive, if * sign_flag = 1 then the sign bit is random as well * @return a random float */ float randf(int min_exp, int max_exp, char sign_flag) { assert(min_exp <= max_exp); int min_exp_mod = min_exp + 126; int sign_mod = sign_flag + 1; int frac_mod = (1 << 23); int s = rand() % sign_mod; // note x % 1 = 0 int e = (rand() % max_exp) + min_exp_mod; int f = rand() % frac_mod; int tmp = (s << 31) | (e << 23) | f; float r = (float)*((float*)(&tmp)); /** uncomment if you want to see the structure of the float. */ // printf("%x, %x, %x, %x, %f\n", (s << 31), (e << 23), f, tmp, r); return r; }` `

` `#include <random> //If it doesnt work then use #include <tr1/random> #include <iostream> using namespace std; typedef std::tr1::ranlux64_base_01 Myeng; typedef std::tr1::normal_distribution<double> Mydist; int main() { Myeng eng; eng.seed((unsigned int) time(NULL)); //initializing generator to January 1, 1970); Mydist dist(1,10); dist.reset(); // discard any cached values for (int i = 0; i < 10; i++) { std::cout << "a random value == " << (int)dist(eng) << std::endl; } return (0); }` `

rand（）在0和RAND_MAX之间返回一个int值。 要得到一个介于0.0和1.0之间的随机数，首先将rand返回的int返回值转换为一个float值，然后除以RAND_MAX。

` `static float frand(){ float f; UINT32 *fi = (UINT32*)&f; *fi = 0; const int minBitsRandGives = (1<<15); // RAND_MAX is at least (1<<15) UINT32 randExp = (rand()%254)+1; // Exponents are in range of [1..254] UINT32 randMantissa = ((rand() % minBitsRandGives) << 8) | (rand()%256); *fi = randMantissa | (randExp<<23); // Build a float with random exponent and random mantissa return f; }` `