Java求PI的几种方法

前几天闲的没事,就想用Java算出圆周率,自己想和上网查资料,总结了几种方法。

1.利用概率法,这是算法课上看ppt看到的,大致就是如下,随机掷点,落到扇形里的点数为k,总共为n,当然所有点都落到了正方形里面,当掷的点数足够多时,PI就越来越精确到实际值。程序如下:

图片

public class PI {

	public static void main(String[] args) {
		Scanner input  = new Scanner(System.in);
		System.out.println("输入循环次数");
		BigDecimal n = new BigDecimal(input.nextLine());
		System.out.println(n);
		BigDecimal k = BigDecimal.ZERO;
		BigDecimal four = new BigDecimal("4");
		for(BigDecimal i= BigDecimal.ONE;(i.compareTo(n))<0;i = i.add(BigDecimal.ONE)) {
			double x = (double) (Math.random()*1);
			double y = (double) (Math.random()*1);
			if(x*x+y*y<1) {
				k=k.add(new BigDecimal("1"));
			}
			System.out.println(k+"  "+n+"  ");
			System.out.println("PI:"+ k.divide(i,20,BigDecimal.ROUND_UP).multiply(four)+"\n");
		}
		System.out.println("PI:"+ k.divide(n,20,BigDecimal.ROUND_UP).multiply(four)+"\n");
	}
}

2利用公式

.图片

代码如下:

public class PI_3 {

	public static void main(String[] args) {
		  double sum = 0;
		  int a;
		  for (int k = 1; k <= 50; k++) {
			  a=k*10000000;
			  for (int i = 1; i <=a; i += 2) {
			  sum += 4 * (1.0 / (2 * i - 1) - 1.0 / (2 * i + 1));
			  }
		  	  System.out.println("结果是"+sum);
		      sum=0;
		  }
		 
	}

}

3.利用公式

其中

代码如下:

public class PI_2 {

	private static final BigDecimal FOUR = BigDecimal.valueOf(4);
    private static final int roundingMode = BigDecimal.ROUND_HALF_EVEN;
    private static BigDecimal result;

    public static void main(String[] args) {
        Runnable r= new Runnable() {
            public void run() {
                result = computePi(500);
            }
        };
        Thread t=new Thread(r);
        t.start();
        try {
            t.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(result);

    }

    public static BigDecimal computePi(int diigits){
        int scale = diigits+5;
        BigDecimal arctan1_5 = arctan(5,scale);
        BigDecimal arctan1_239= arctan(239, scale);
        BigDecimal pi = arctan1_5.multiply(FOUR).subtract(arctan1_239).multiply(FOUR);
        return pi.setScale(diigits,BigDecimal.ROUND_HALF_UP);

    }

    private static BigDecimal arctan(int inversex, int scale) {
        BigDecimal result , numer , term;
        BigDecimal invX = BigDecimal.valueOf(inversex);
        BigDecimal invY = BigDecimal.valueOf(inversex*inversex);
        numer = BigDecimal.ONE.divide(invX, scale, roundingMode);
        result = numer;
        int i = 1;
        do{
            numer=numer.divide(invY, scale, roundingMode);
            int denom = 2*i+1;
            term = numer.divide(BigDecimal.valueOf(denom), scale, roundingMode);
            if((i%2)!=0){
                result = result.subtract(term);
            }else {
                result = result.add(term);
            }
            i++;
        }while(term.compareTo(BigDecimal.ZERO)!=0);
        return result;
    }
}

4.利用公式

代码如下:

public class PI_4 {

	public static void main(String[] args) {
        final int PRECISION = 100;//计算精度
        final int THENUMBEROFCIRCLES = 1000;//循环次数
        BigDecimal PI = new BigDecimal(0);
        System.out.println("正在计算中...请稍后...");
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < THENUMBEROFCIRCLES; i++) {
            //PI=PI+1/16^i(4/(8i+1)-2/(8i+4)-1/(8n+5)-1/(8n+6))
            PI = PI.add((BigDecimal.valueOf(1).divide(BigDecimal.valueOf(16).pow(i))).multiply((BigDecimal.valueOf(4)
                    .divide(BigDecimal.valueOf(8).multiply(BigDecimal.valueOf(i)).add(BigDecimal.valueOf(1)), PRECISION, BigDecimal.ROUND_DOWN))//ROUND_DOWN接近零的舍入模式(截取)  
                    .subtract(BigDecimal.valueOf(2).divide(BigDecimal.valueOf(8).multiply(BigDecimal.valueOf(i)).add(BigDecimal.valueOf(4)), PRECISION,BigDecimal.ROUND_DOWN))
                    .subtract((BigDecimal.valueOf(1).divide(BigDecimal.valueOf(8).multiply(BigDecimal.valueOf(i)).add(BigDecimal.valueOf(5)), PRECISION,BigDecimal.ROUND_DOWN)))
                    .subtract((BigDecimal.valueOf(1).divide(BigDecimal.valueOf(8).multiply(BigDecimal.valueOf(i)).add(BigDecimal.valueOf(6)), PRECISION,BigDecimal.ROUND_DOWN)))));
        }
        System.out.println("PI=" + PI.setScale(PRECISION, BigDecimal.ROUND_DOWN) + "\n共用时:"//输出精度设置成30
                + (System.currentTimeMillis() - startTime) / 1000.0 + "秒");
    }
}

其中2,3,4都是利用级数的收敛算出的PI,结果较为准确,做完这个之后想,高数对编程还是有帮助的嘛,那么,坚定考研这条路线了,前些天看到别人拿到offer了一度想直接出去找工作的想法,但后来和同学聊起这个来,认为直接出去大多都是一直做着那些没技术的活,到了三四十公司就会不要你了,大批引进新人,购买廉价劳动力,要想让公司不放你走,还是得掌握些核心科技,所以得尽早接触IT这领域的前沿知识技术,考研是一个不错的选项。OK,终于写完了,以后会时常到博客里发些平时掌握的知识技能,其实一直想让我的博客成为那些大牛的博客一样,每篇文章都有几万的阅读量,以前遇到不会的动不动就到 csdn下搜别人写的文章,要是有一天很多人也能搜我文章获得他们想要的知识呢。不能在这么懒惰下去,这个号好久没有更过文章,今天起会时常更,在将来的某一天,翻看自己博客时,能有几十页的文章可以看,那成就感想想就好。OK,就到这里,还得赶紧写我的编译原理 ,ORACLE作业呢.......

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值