圆周率计算(祖冲之计算圆周率的方式,java实现)

23 篇文章 3 订阅
4 篇文章 0 订阅

目录

来历

图形辅助说明

代码实现

运行效果

圆周率,前500位

■BigDecimal实现(更精确---3.1415926535897)

代码

效果


=====

来历

祖冲之(约公元3世纪,南北朝时期人)

当祖冲之计算圆周率时,他采用了一种称为“多边形逼近法”的方法。这种方法涉及到把一个圆划分成许多小的多边形,然后计算这些多边形的周长,以逼近圆周率的值。

----------

魏晋时期的刘徽,他在《九章算术》中提出了多边形逼近圆的方法。

祖冲之通过不断增加多边形的边数,逐步逼近圆形,从而得到更精确的圆周率值。尽管这种方法在当时是非常耗时和耐心的,但祖冲之坚持不懈地进行计算,最终得出了比较准确的结果。这种方法展现了祖冲之在数学上的才华和毅力,对中国古代数学的发展产生了重大影响。

---

《九章算术》,算学书。作者不详。西汉早期丞相张苍 、耿寿昌等增补删订,三国曹魏时期刘徽注释,唐初李淳风注,作为通行本。

图形辅助说明

 //  Cn+1 = { 【 「(Cn)平方-1的平方」开根号   +  (Cn) 】的平方  +  1的平方 } 开根号
c = Math.sqrt( 2 * c * c  + 2 * Math.sqrt(c * c - 1) * c) ;

代码实现

====

package com.sxz.calc.pai;


public class ZuchongzhiPiApproximation {

	/**
	 * https://blog.csdn.net/weixin_42710740/article/details/121651345
	 * 
	 * https://blog.csdn.net/sxzlc/article/details/139911309
	 * 
	 * @param args
	 */
	public static void main(String[] args) {

		double degre = 45;
		double c = Math.sqrt(2);
		System.out.println("斜边长:" + c);
		int n = 14; // 切割次数
		int numberOfSides = 4 << n; // 多边形边数
		int numberOfSides2 = 4; // 多边形边数

		for (int i = 1; i <= n; i++) {

			System.out.print("圆形内四边形切割次数:" + i);
			
			degre = degre / 2;
			System.out.print( "---C" + (i+1) +"----度角数:"+"----" + degre );

			numberOfSides2 = numberOfSides2 * 2;
			System.out.print("-----多边形边数:" + numberOfSides2);
			
			//  Cn+1 = { 【 「(Cn)平方-1的平方」开根号   +  (Cn) 】的平方  +  1的平方 } 开根号
			c = Math.sqrt( 2 * c * c  + 2 * Math.sqrt(c * c - 1) * c) ;
			
			double pi = numberOfSides2 / c ;
			System.out.print("-----圆周率:" + pi);
			
			System.out.println("-----------斜边长:" + c);

		}
		System.out.println("多边形边数:" + numberOfSides);
		// 多边形 变长 2,上面 三角形中 , 短直角边变长 1
		System.out.println("多边形 变长 2,上面 三角形中 , 短直角边变长 1");
		// System.out.println(numberOfSides *2/ (c*2) );
		System.out.println(numberOfSides / c );
	}
}

====

运行效果

===

多边形 变长 2,下面面 三角形中 , 短直角边变长 1 (图中粉丝部分)

==

设多边形变长为2,
直接三角形短边即为1,
角度每次减半,短边直角边为1时,对应的斜边长。

斜边长,既是半径的长度!!!

===

==

多边形边数:65536
3.1415926523865902

===

圆周率,前500位

3.14159 26535 89793 23846 26433
83279 50288 41971 69399 37510
58209 74944 59230 78164 06286
20899 86280 34825 34211 70679
82148 08651 32823 06647 09384
46095 50582 23172 53594 08128
48111 74502 84102 70193 85211
05559 64462 29489 54930 38196
44288 10975 66593 34461 28475
64823 37867 83165 27120 19091
45648 56692 34603 48610 45432
66482 13393 60726 02491 41273
72458 70066 06315 58817 48815
20920 96282 92540 91715 36436
78925 90360 01133 05305 48820
46652 13841 46951 94151 16094
33057 27036 57595 91953 09218
61173 81932 61179 31051 18548
07446 23799 62749 56735 18857
52724 89122 79381 83011 94912

■BigDecimal实现(更精确---3.1415926535897932)

代码

package com.sxz.calc.pai;

import java.math.BigDecimal;

public class ZuChongzhiPiBigDecimal {
	
	//精确小数位数,越精确,效率越低
    public static int SCALE_DOUBLE = 5;
	
    public static void main(String[] args) {

		int scale = 33;
    	
        BigDecimal degre = new BigDecimal("45");
        BigDecimal c = calculateSqrt(new BigDecimal("2"), scale);
        System.out.println("斜边长:" + c);

        int n = 27; // 切割次数
        int numberOfSides =4 << n; // 多边形边数
        BigDecimal sides = new BigDecimal(numberOfSides);
        int numberOfSides2 = 4; // 多边形边数

        for (int i = 1; i <= n; i++) {

            System.out.print("圆形内四边形切割次数:" + i);

            degre = degre.divide(new BigDecimal("2"));
            System.out.print("---C" + (i + 1) + "----度角数:" + "----" + degre);

            numberOfSides2 = numberOfSides2 * 2;
            System.out.print("-----多边形边数:" + numberOfSides2);

            // Cn+1 = { 【 「(Cn)平方-1的平方」开根号 + (Cn) 】的平方 + 1的平方 } 开根号
            // c = Math.sqrt( 2 * c * c  + 2 * Math.sqrt(c * c - 1) * c) ;
            BigDecimal cStep1 = new BigDecimal("1");
            BigDecimal cStep2 = new BigDecimal("1");
            BigDecimal cStep3 = new BigDecimal("1");
            
			cStep1 = c.multiply(c).multiply(new BigDecimal("2"));
			cStep2 = calculateSqrt(c.multiply(c).subtract(new BigDecimal("1")), scale).multiply(new BigDecimal("2"))
					.multiply(c);
			cStep3 = calculateSqrt(cStep1.add(cStep2), scale);
            c = cStep3;
            
            BigDecimal pi = new BigDecimal(numberOfSides2).divide(c, scale, BigDecimal.ROUND_HALF_UP);
            System.out.print("-----圆周率:" + pi);

            System.out.println("-----------边长:" + c);

        }
        System.out.println("多边形边数:" + numberOfSides);
        // 多边形 变长 2,上面 三角形中 , 短直角边变长 1
        System.out.println("多边形 变长 2,上面 三角形中 , 短直角边变长 1");
        System.out.println(sides.divide(c, 30, BigDecimal.ROUND_HALF_UP));
    }
    
    /**
     * 
     * @param n
     * @param scale 精度
     * @return
     */
    public static BigDecimal calculateSqrt(BigDecimal n, int scale) {
        BigDecimal sqrt = new BigDecimal("1");
        BigDecimal tolerance = new BigDecimal("0.0000001");

        BigDecimal diff = new BigDecimal("1");

        while (diff.abs().compareTo(tolerance) > 0) {
            BigDecimal previousSqrt = sqrt;
            sqrt = n.divide(sqrt, scale, BigDecimal.ROUND_HALF_UP).add(sqrt).divide(new BigDecimal("2"), scale, BigDecimal.ROUND_HALF_UP);
            diff = sqrt.subtract(previousSqrt);
        }

        return sqrt;
    }

}

效果

===

===

==

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我并不能提供完整的Java代码,但是我可以提供一些思路和代码片段,希望能够帮助到你。 首先,我们需要使用Hadoop分布式计算框架来实现圆周率计算。Hadoop提供了MapReduce框架,我们可以使用它来实现并行计算。具体步骤如下: 1. 首先,我们需要将圆的面积和正方形的面积分别计算出来。这里可以使用Monte Carlo方法,即随机投点的方法来实现。我们可以在Map函数中生成随机点,并将这些点发送到Reduce函数中进行计算。 2. 在Map函数中,我们需要生成随机点,并判断这些点是否在圆内。如果是,则将1发送到Reduce函数中,否则将0发送到Reduce函数中。代码如下: ```java public static class PiMapper extends Mapper<Object, Text, NullWritable, IntWritable> { private final static IntWritable one = new IntWritable(1); private final static NullWritable nullWritable = NullWritable.get(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { int n = Integer.parseInt(value.toString()); Random random = new Random(); int count = 0; for (int i = 0; i < n; ++i) { double x = random.nextDouble(); double y = random.nextDouble(); if (x * x + y * y <= 1) { count += 1; } } context.write(nullWritable, new IntWritable(count)); } } ``` 3. 在Reduce函数中,我们需要将所有的1相加,得到圆内点的个数。然后,我们可以根据圆内点的个数和总点数来计算圆的面积和正方形的面积。最后,我们可以通过圆的面积和正方形的面积来计算圆周率。代码如下: ```java public static class PiReducer extends Reducer<NullWritable, IntWritable, NullWritable, DoubleWritable> { private final static NullWritable nullWritable = NullWritable.get(); public void reduce(NullWritable key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int count = 0; for (IntWritable val : values) { count += val.get(); } double pi = 4.0 * count / n; context.write(nullWritable, new DoubleWritable(pi)); } } ``` 4. 最后,我们需要在Driver函数中设置MapReduce的参数,并提交作业。代码如下: ```java public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "pi"); job.setJarByClass(Pi.class); job.setMapperClass(PiMapper.class); job.setReducerClass(PiReducer.class); job.setOutputKeyClass(NullWritable.class); job.setOutputValueClass(IntWritable.class); job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } ``` 注意,这里的n是总点数,需要从命令行参数中获取。另外,需要将输出转换为DoubleWritable类型,以便输出圆周率。 希望这些代码片段能够帮助到你,如果有不清楚的地方,可以提出来,我会进一步解答。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值