//dsd的概率论大作业
平面上画着两条间距a的平行线,随机地向此平面任投掷一长度为l ( l < a )的针N次,观察针与直线相交的次数记为n,计算此针与直线相交的概率。
以x表示针的中点距离最近的一条平行线的距离,φ表示针与平行线的夹角,则可得0≤x≤a/2,0≤φ≤π,要使得针与平行线相交,必须保证x≤1/2lsinφ。
代码:
#include<stdio.h>
#define _USE_MATH_DEFINES
#include<math.h>
#include<stdlib.h>
#include<time.h>
int main()
{
long int n=0; //相交次数
long int N=0; //投针次数
int l=100; //针的长度
int a=200; //平行线间距
double distance=0; //落点距离
double angle=0; //角度
double P; //频率
double pi=0; //最终得到pi
int i=0; //循环变量
printf("输入要投的针数:"); //确定实验次数
scanf_s("%d", &N);
srand(time(NULL));
for (i = 0; i < N; i++) //进行循环试验
{
distance = rand() % (l + 1);
angle = rand() % 91;
if (distance <= 0.5 * l * sin(angle * M_PI / 180))
n++; //相交次数计数
}
P= (double)n / (double)N;
pi=2.0 * (double)l / ((double)a * P);
printf("计算得到圆周率π为:%lf\n", pi); //输出结果
}
注意:
强制类型转换才能克服整除;
M_PI只有声明#define _USE_MATH_DEFINES后才可以使用参考的π值。
实验结果如下:
N(投针次数) | 输出结果 |
10 | 3.333333 |
100 | 3.333333 |
1000 | 3.300330 |
10000 | 3.210273 |
100000 | 3.112065 |
1000000 | 3.132960 |
10000000 | 3.133065 |
100000000 | 3.131318 |
1000000000 | 3.131390 |
从实验结果可以看出,随着试验次数的增多,频率逐渐趋近概率,可以预见到如果试验次数足够多,能够得到更加精确的圆周率值。
由于C语言中rand函数实际上为伪随机数,所以得到的结果有一定的伪随机性。
C语言中无法用弧度制表示角度,因此在程序中得到随机的角度angle值时,实际需要用math.h文件中自定义的π值进行一遍换算,在上述代码中M-PI将被扩展为3.14159265358979323846,这也带来了实验结果的不准确性,故而会影响最终输出的π的值。从表中也可以看到,结果始终与3.14159265……相差一定的偏差。
如果能有更好的转换角度的方式,也许可以提高c语言随机试验程序的精度。
代码内容参考了http://t.csdn.cn/IO92R。