问题在于 rand() 在域 [0,RAND_MAX] 上为您提供了均匀分布的变量,RAND_MAX 很可能是 32767。您不能通过简单的乘法将此域映射到更大的域
u=(double)rand();
d=(double)RAND_MAX;
double div= u/d;
double res=div*interval_range;
因为只有当 RAND_MAX 是 interval_range 的偶数倍时,这才是正确的。但是,您将不会在更大的域中拥有所有值。但是,如果您的新的所需域小于RAND_MAX,您可以将rand() 生成的均匀分布截断到您想要的域(本质上意味着拒绝大于您所需域的rand() 值)。截断的均匀分布仍然是均匀的,因此您将在新域上拥有新的均匀分布变量(这将是更准确的条件分布)。统计示例:
因此截断的均匀分布将具有另一个“矩”,即描述它的参数(均值、std_dev、方差等),但将再次保持均匀。
示例代码:
int main{
int o=RAND_MAX;
std::map<int,int> m1;
int min=0,max=999;
for (int i=0; i<1000*9994240; ++i){//9994240=305*32768 32768=RAND_MAX+1
int r=rand();
if(r<=max){
m1[r]++;
}
}
for (auto & i : m1)
std::cout << i.first << " : " << i.second << '\n';
}
结果:
0:42637
1:42716
2:42590
3:42993
4:42936
5 : 42965
6 : 42941
7 : 42705
8 : 42944
9 : 42707
10 : 42860
11 : 43012
12 : 42793
//...
995 : 42861
996 : 42911
997 : 42865
998 : 42877
999 : 43159
您可以通过这种方式在任何域上获得所需的结果:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 1000);
for (int n=0; n<1000; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
但是在这种情况下你真的应该使用 boost:
#include <iostream>
#include "boost/random.hpp"
#include "boost/generator_iterator.hpp"
using namespace std;
int main() {
typedef boost::mt19937 RNGType;
RNGType rng;
boost::uniform_int<> zero_to_n( 0, 999 );
boost::variate_generator< RNGType, boost::uniform_int<> >
dice(rng, zero_to_n);
int n = dice();
}