加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

借助Java随机数计算圆周率π

发布时间:2021-11-19 16:15:28 所属栏目:教程 来源:互联网
导读:一、理论篇 1. 数学公式 圆面积公式:*r*r,其中为圆周率,r为圆半径; 正方形面积公式:s*s,其中s为边长; 勾股定理:a*a + b*b = c*c,其中a/b分别为直角三角形的两个直角边,c为斜边。 2. 计算方法 考虑下图,边长为r的正方形内嵌了一个以r为半径的1/4圆

一、理论篇
 
1. 数学公式
 
圆面积公式:π*r*r,其中π为圆周率,r为圆半径;
 
正方形面积公式:s*s,其中s为边长;
 
勾股定理:a*a + b*b = c*c,其中a/b分别为直角三角形的两个直角边,c为斜边。
 
2. 计算方法
 
考虑下图,边长为r的正方形内嵌了一个以r为半径的1/4圆。
 
利用Java随机数计算圆周率π
 
InsideCircle面积 = 以r为半径的圆面积 / 4 = π*r*r/4
 
正方形面积 = r*r
 
所以, InsideCircle面积 / 正方形面积 = (π*r*r/4) / (r*r) = π/4
 
面由线组成,线由点组成。因此,如果有若干点均匀落入到正方形中,那么落入InsideCircle的点的个数占总数的比率也将会是π/4,由此将会统计出π的值。
 
二、实战篇
 
1. 散弹枪计算
 
具体方式为:制作一个如上图一样正方形木板,用散弹枪对着它一顿乱扫,最后统计弹孔个数和落点,从而得出π的值。
 
事实上,真的有研究人员做过这个脑洞大过黑洞的实验,他们在 30857 个样本中得到了 3.13 这个还算不错的结果。
 
详见:http://www.linuxidc.com/Linux/2015-01/111775.htm
 
2. Java随机数计算
 
作为一个码农,当然玩不起散弹枪这种高级玩具,那么接下来就以代码来玩一把。
 
具体思路是这样的:r直接取值为1.0,还需要定义一个落在正方形中的所有点的个数PointNumber,每一个点都有一个坐标(x,y),x,y取值为0.0-1.0,利用Java随机数生成每个点,然后用勾股定理判断该点是落在圆内还是圆外,并统计落在圆内的点的个数InsideCircleNumber,那么π=InsideCircleNumber/PointNumber*4。当然,如果只计算一次的话,可能误差会较大,可以再增加一个计算次数CalcTimes,然后求平均值。
 
按照这样的思路的计算结果如下:
 
PointNumber
 
CalcTimes
 
π
 
最接近π的值
 
10000
 
10000
 
3.141617279999959
 
3.1416
 
100000
 
10000
 
3.1415569599999684
 
3.1416
 
1000000
 
10000
 
3.1415845499999953
 
3.141592
 
10000000
 
10000
 
3.1415924761886806
 
3.1415928
 
附源代码:
package com.test.pai;
import org.apache.commons.lang.math.RandomUtils;
public class CalcPai         
{           
    public static boolean inCircle(double x, double y)           
    {           
        return (y <= Math.sqrt(1 - x * x));           
    }
    public static double CalcPaiByPointNumber(long num)         
    {           
        double inCircleNum = 0.0;           
        for (long i = 0; i < num; i++)           
        {           
            if (CalcPai.inCircle(RandomUtils.nextDouble(), RandomUtils.nextDouble()))           
            {           
                inCircleNum++;           
            }           
        }
        double pai = inCircleNum * 4 / num;
        return pai;         
    }
    public static void main(String[] args)         
    {           
        double realPai = 3.14159265;           
        CurrResult currResult = new CurrResult(0.0, realPai, 0.0);           
        long times = 10000;           
        long num = 1000000;           
        for (long i = 1; i <= times; i++)           
        {
            double pai = CalcPai.CalcPaiByPointNumber(num);         
            currResult.setTotalPai(currResult.getTotalPai() + pai);           
            double diff = Math.abs(realPai - pai);           
            if (diff < currResult.getDifference())           
            {           
                currResult.setCurrPai(pai);           
                currResult.setDifference(diff);           
            }
            System.out.println("No." + i + "/" + times + "t" + pai + "t" + currResult.getCurrPai() + "t"         
                    + currResult.getTotalPai() / i);           
        }
    }
}
 

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读