重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
C语言中计算一个数的N次方可以用库函数pow来实现。
创新互联是一家专注于网站设计制作、成都做网站与策划设计,港口网站建设哪家好?创新互联做网站,专注于网站建设十余年,网设计领域的专业建站公司;建站业务涵盖:港口等地区。港口做网站价格咨询:13518219792
函数原型:double pow(double x, double y);
功 能:计算x^y的值
返 回 值:计算结果
举例如下:
double a = pow(3.14, 2); // 计算3.14的平方
注:使用pow函数时,需要将头文件#includemath.h包含进源文件中。
用boost的random库方便生成,以下是2个测试,分别生成50个数:
// μ = 30, δ^2 = 4
30.84 30.00 26.61 27.49 31.27
29.74 27.99 29.81 29.73 33.29
32.17 31.37 26.83 28.20 27.99
28.69 34.66 25.44 29.22 24.84
29.39 32.02 32.35 28.28 34.16
27.04 32.02 33.40 31.39 29.08
31.91 29.19 29.14 32.25 27.20
32.16 29.06 27.67 29.26 29.51
28.36 28.65 26.87 27.74 26.56
30.16 31.18 30.57 30.57 33.43
// μ = 30, δ^2 = 100
84.66 61.85 24.17 68.63 2.15
1.30 40.92 72.74 74.83 4.25
39.86 27.06 60.94 50.58 79.35
51.83 86.03 74.75 92.33 70.59
93.43 55.51 57.22 70.48 70.52
1.45 22.55 40.85 33.23 65.39
35.54 89.69 45.87 88.35 40.73
67.31 17.64 23.98 98.43 35.93
97.88 48.95 59.54 13.14 45.79
5.55 8.77 70.31 14.83 82.54
#include iostream
#include boost/random.hpp
using namespace std;
typedef boost::minstd_rand GenType;
typedef boost::normal_distribution NormalDis;
typedef boost::variate_generatorGenType, NormalDis RNG;
void Show(RNG rng)
{
cout.setf(ios_base::fixed);
cout.precision(2);
for(int i = 0; i 50;)
{
double temp = rng();
if(temp = 1 temp = 100)
{
cout temp ' ';
if(++i % 5 == 0)
cout '\n';
}
else
continue;
}
cout endl;
}
int main()
{
GenType gt;
NormalDis dis(30, 2); // μ = 30, δ^2 = 4
RNG rng(gt, dis);
Show(rng);
rng.distribution() = NormalDis(30, 100); // μ = 30, δ^2 = 10000
Show(rng);
}
#include math.h
#include stdlib.h
#include time.h
#include stdio.h
#define pi 3.1415926535897
// 区间[min,max]上的均匀分布,min和max要求传入的参数类型一致
template class T
T rand(T min, T max)
{
return min + (max - min) * rand() / (RAND_MAX + 1.0);
}
// 求均值为miu,方差为sigma的正太分布函数在x处的函数值
double normal(double x, double miu,double sigma)
{
return 1.0 / sqrt(2.0 * pi) / sigma * exp(-1.0 * (x - miu) * (x - miu) / (2.0 * sigma * sigma));
}
//按照矩形区域在函数值曲线上下位置分布情况得到正太函数x值
double randn(double miu, double sigma, double min , double max)
{
double x, y, dScope;
do
{
x = rand(min,max);
y = normal(x,miu,sigma);
dScope = rand(0.0, normal(miu,miu,sigma));
}
while(dScope y);
return x;
}
// 简单算法,实际结果和公式法差不多
#define rd (rand()/(RAND_MAX+1.0))
double randn(double miu, double sigma)
{
return (rd + rd + rd + rd + rd + rd + rd + rd + rd + rd + rd + rd - 6.0) * 0.5 * sigma + miu;
}
void main()
{
int i;
srand((unsigned)time( NULL ));
for (i = 0; i 128; i++)
{
printf("%f%c", randn(2.0, 0.4), (i % 8 == 7) ? '\n' : ' ');
}
printf("\n");
for (i = 0; i 128; i++)
{
printf("%f%c", randn(2.0, 0.4, 0.0, 4.0), (i % 8 == 7) ? '\n' : ' ');
}
printf("\n");
}
摘要:
随机数在实际运用中非常之多,如游戏设计,信号处理,通常我们很容易得到平均分布的随机数。但如何根据平均分布的随机数进而产生其它分布的随机数呢?本文提出了一种基于几何直观面积的方法,以正态分布随机数的产生为例讨论了任意分布的随机数的产生方法。
大家都知道,随机数在各个方面都有很大的作用,在vc的环境下,为我们提供了库函数rand()来产生一个随机的整数。该随机数是平均在0~RAND_MAX之间平均分布的,RAND_MAX是一个常量,在VC6.0环境下是这样定义的:
#define RAND_MAX 0x7fff
它是一个short 型数据的最大值,如果要产生一个浮点型的随机数,可以将rand()/1000.0这样就得到一个0~32.767之间平均分布的随机浮点数。如果要使得范围大一点,那么可以通过产生几个随机数的线性组合来实现任意范围内的平均分布的随机数。例如要产生-1000~1000之间的精度为四位小数的平均分布的随机数可以这样来实现。先产生一个0到10000之间的随机整数。方法如下 :
int a = rand()%10000;
然后保留四位小数产生0~1之间的随机小数:
double b = (double)a/10000.0;
然后通过线性组合就可以实现任意范围内的随机数的产生,要实现-1000~1000内的平均分布的随机数可以这样做:
double dValue = (rand()%10000)/10000.0*1000-(rand()%10000)/10000.0*1000;
则dValue就是所要的值。
到现在为止,你或许以为一切工作都已经完成了,其实不然,仔细一看,你会发现有问题的,上面的式子化简后就变为:
double dValue = (rand()%10000)/10.0-(rand()%10000)/10.0;
这样一来,产生的随机数范围是正确的,但是精度不正确了,变成了只有一位正确的小数的随机数了,后面三位的小数都是零,显然不是我们要求的,什么原因呢,又怎么办呢。
先找原因,rand()产生的随机数分辨率为32767,两个就是65534,而经过求余后分辨度还要减小为10000,两个就是20000而要求的分辨率为1000*10000*2=20000000,显然远远不够。下面提供的方法可以实现正确的结果:
double a = (rand()%10000) * (rand()%1000)/10000.0;
double b = (rand()%10000) * (rand()%1000)/10000.0;
double dValue = a-b;
则dValue就是所要求的结果。在下面的函数中可以实现产生一个在一个区间之内的平均分布的随机数,精度是4位小数。
double AverageRandom(double min,double max)
{
int minInteger = (int)(min*10000);
int maxInteger = (int)(max*10000);
int randInteger = rand()*rand();
int diffInteger = maxInteger - minInteger;
int resultInteger = randInteger % diffInteger + minInteger;
return resultInteger/10000.0;
}
但是有一个值得注意的问题,随机数的产生需要有一个随机的种子,因为用计算机产生的随机数是通过递推的方法得来的,必须有一个初始值,也就是通常所说的随机种子,如果不对随机种子进行初始化,那么计算机有一个确省的随机种子,这样每次递推的结果就完全相同了,因此需要在每次程序运行时对随机种子进行初始化,在vc中的方法是调用srand(int)这个函数,其参数就是随机种子,但是如果给一个常量,则得到的随机序列就完全相同了,因此可以使用系统的时间来作为随机种子,因为系统时间可以保证它的随机性。
调用方法是srand(GetTickCount()),但是又不能在每次调用rand()的时候都用srand(GetTickCount())来初始化,因为现在计算机运行时间比较快,当连续调用rand()时,系统的时间还没有更新,所以得到的随机种子在一段时间内是完全相同的,因此一般只在进行一次大批随机数产生之前进行一次随机种子的初始化。下面的代码产生了400个在-1~1之间的平均分布的随机数。
double dValue[400];
srand(GetTickCount());
for(int i= 0;i 400; i++)
{
double dValue[i] = AverageRandom(-1,1);
}
double gaussian(double u) //用Box_Muller算法产生高斯分布的随机数
{
double r,t,z,x;
double s1,s2;
s1=(1.0+rand())/(RAND_MAX+1.0);
s2=(1.0+rand())/(RAND_MAX+1.0);
r=sqrt(-2*log(s2)/log(e));
t=2*pi*s1;
z=r*cos(t);
x=u+z*N;
return x;
}
以前写的一个函数,u是均值,N是方差
调试程序时,随机数种子可以设常数,例如srand(54321);
用 rand() 产生均匀分布随机数 x1,x2
利用瑞利分布得正态分布随机数 y1,y2
再按要求线性缩放一下到[0.01,2] 区间。
#include stdio.h
#include stdlib.h
#include math.h
#include time.h
main(){
#define N 100
double rd[N];
double x1,x2,y1,y2;
double pi2=6.28318530728,mx,mi,ave=0;
int i;
//srand(54321);
srand(time(NULL));
for (i=0;i=N-2;i=i+2){
x1=1.0*rand()/RAND_MAX;
x2=1.0*rand()/RAND_MAX;
y1= sqrt((-2.0*log(x1))) * cos(pi2*x2);
y2= sqrt((-2.0*log(x1))) * sin(pi2*x2);
rd[i]=y1;
rd[i+1]=y2;
}
mx=rd[0];mi=rd[0];
for (i=0;iN;i++){
if (rd[i]mx)mx=rd[i];
if (rd[i]mi)mi=rd[i];
}
//printf("mi=%lf mx=%lf\n",mi,mx);
for (i=0;iN;i++) rd[i] = (rd[i]-mi)/(mx-mi+0.001) * (2.0-0.01) + 0.01;
for (i=0;iN-2;i=i+2) printf("%lf %lf\n",rd[i],rd[i+1]);
return 0;
}