搜索
查看: 1529|回复: 7
打印 上一主题 下一主题

用c语言小算法测算圆周率π,未果~

[复制链接]
跳转到指定楼层
楼主
发表于 2016-3-19 14:21:28 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
5啊哈币
记得中学的时候,那个时候学Qbasic,老师讲了一种方法计算圆周率。简单的想法(姑且也能叫算法吧)就是通过“撒子儿”。
在一块100*100的范围内,随机撒子儿,落到1/4圆饼范围的子儿的概率(范围内次数/总次数),即是1/4圆饼与整个方块的面积比值。
撒子数量越多,推算出来的π值就约准确。
有一张简图示意:(原谅圆弧线画得不好)


初步写的代码如下,但是在Xcode(苹果系统的编译器)里面运行结果总是不对(每次π都是4.000000),望指点!

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
    float pi;//定义圆周率要用浮动变量
    int i=1,n,sum=0,x,y;
    puts("请输入需要测算的精度n");//n表示撒子儿次数
    scanf("%d",&n);
    while(i<=n)
    {
        i++;
        srand((unsigned)time(NULL));//前面对应头文件<stdlib.h>和<time.h>
        x=rand()%100+1;//撒子儿的横坐标值
        y=rand()%100+1;//撒子儿的纵坐标值
        if ((x*x)+(y*y)<=10000) sum++;//如果撒子位置落入1/4圆范围内,sum计数一次
    }
    pi=4*sum/n;//根据撒子位置的概率,结合面积关系,计算出圆周率
    printf("%f %d\n",pi,sum);
    return 0;
}


最佳答案

查看完整内容

提供一种写法
沙发
发表于 2016-3-19 14:21:29 | 只看该作者
提供一种写法
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>

  4. int main()
  5. {
  6.     int i, n;
  7.     int hit = 0;
  8.     scanf("%d", &n);
  9.     srand(time(NULL));
  10.     for(i=0; i<n; ++i){
  11.         double x, y;
  12.         x = rand() / (RAND_MAX + 1.0);
  13.         y = rand() / (RAND_MAX + 1.0);
  14.         if(x*x + y*y < 1)
  15.             hit += 1;
  16.     }
  17.     printf("%f\n", 4.0 * hit / n);
  18.     return 0;
  19. }
复制代码
板凳
发表于 2016-3-19 16:03:41 | 只看该作者
首先是
pi=4*sum/n;
这里

4*sum/n是整数,应该转换成浮点数 4.0 * sum / n

然后随机数种子只应该被初始化一次
srand((unsigned)time(NULL));
while(i<=n)
    {
        i++;
……

最后让x,y都是1-100之间的整数不正确,x和y应该在0-100之前分布,而不是离散分布
地板
 楼主| 发表于 2016-3-19 17:30:12 | 只看该作者

多谢这位仁兄,借鉴修改后应该成功,仍有几点想刨根问底:

1.在类似“pi=4*sum/n”的赋值运算中,是否如果等号右边全是整型,即便有除法,结果也会自动取整?故而要将4换成4.0.

2.随机数种子明白应该放在循环之外。你写的srand(time(NULL));和我原有的srand((unsigned)time(NULL));之间差异,unsigned应该是指正负符号吧,对运算是否有影响?

3.关于随机数,一开始也考虑应该采用连续而非离散,无奈对rand()函数不够了解(书中也描述不多)
兄台缩写的 rand()/(RAND.MAX+1.0)中,RAND.MAX应该是指随机数的边界,为什么分母要+1.0呢?
5#
发表于 2016-3-19 19:39:56 | 只看该作者
liangchao 发表于 2016-3-19 17:30
多谢这位仁兄,借鉴修改后应该成功,仍有几点想刨根问底:

1.在类似“pi=4*sum/n”的赋值运算中,是否 ...

1. 都是整数的话,就做整数除法,例如 3 / 2得到1, 5 / 2得到2

2. unsigned int和int的范围是不同的,(假设这里的int是int32)一个是从0到大约42亿,一个是从大约-21亿到大约21亿,这里是把time函数返回的一个time_t类型的数字转换成unsigned int,如果要细细追究起来很复杂,没必要强制转换成unsigned

3.分母加1保证是0-1之间的小数,加1.0参考第一条,把整个值转换为浮点数
6#
 楼主| 发表于 2016-3-19 21:59:02 | 只看该作者
rosynirvana 发表于 2016-3-19 19:39
1. 都是整数的话,就做整数除法,例如 3 / 2得到1, 5 / 2得到2

2. unsigned int和int的范围是不同的 ...

关于rand(),稍稍搜了一下
rand()/(RAND_MAX+0.0)与rand()/(RAND_MAX+1.0)的区别
似乎范围区间为:前者是[0,1],而后者是[0,1),是否正确?
如果正确,那在这个算法里,从严谨上考虑,应该用哪个呢?(当然我知道两者区别对最终结果可能甚微)
7#
发表于 2016-3-20 02:00:11 | 只看该作者
liangchao 发表于 2016-3-19 21:59
关于rand(),稍稍搜了一下
rand()/(RAND_MAX+0.0)与rand()/(RAND_MAX+1.0)的区别
似乎范围区间为:前者 ...

一样的,一条线没有面积,所以从理论上来说,在不在边缘线上不影响面积,也就对计算没有影响
8#
 楼主| 发表于 2016-3-20 09:35:25 | 只看该作者
rosynirvana 发表于 2016-3-20 02:00
一样的,一条线没有面积,所以从理论上来说,在不在边缘线上不影响面积,也就对计算没有影响

好吧,了解,谢谢指教~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

广播台
特别关注
快速回复 返回顶部 返回列表