如何用Java实现计算圆周率,支持无限时间一直运算 | 您所在的位置:网站首页 › 无限循环算法公式 › 如何用Java实现计算圆周率,支持无限时间一直运算 |
首先,我们知道计算圆周率最精确的方式: π = 2*(1 + 1/3 + 1/3 * 2/5 + 1/3 * 2/5 * 3/7 + 1/3 * 2/5 * 3/7 * 4/9 + …… ) ; 找到规律, 1.发现第一个数一定是1, 2.然后分子依次是 [1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5] ……无穷 3.分母依次是 [3],[3,5],[3,5,7],[3,5,7,9],[3,5,7,9,11]……无穷 4.然后我开始编码如下: import java.math.BigDecimal; import java.math.RoundingMode; import java.util.LinkedHashMap; import java.util.Map; import java.util.Scanner; public class CalculatePi2 { static final int PRECISION_VALUE = 20000 ; // 计算的 精度值,pi 保留多少位小数 public static void main(String[] args) { Scanner scan=new Scanner(System.in); System.out.println("\n请输入计算次数多少次 :"); // 50 int z=scan.nextInt(); calculate_improve2_byBigDecimal(z) ; } static volatile LinkedHashMap li2 = new LinkedHashMap() ; static final BigDecimal B0 = new BigDecimal("0").setScale(PRECISION_VALUE,RoundingMode.HALF_UP) ; static final BigDecimal B1 = new BigDecimal("1").setScale(PRECISION_VALUE,RoundingMode.HALF_UP) ; static final BigDecimal B2 = new BigDecimal("2").setScale(PRECISION_VALUE,RoundingMode.HALF_UP) ; static volatile BigDecimal sum = new BigDecimal("0").setScale(PRECISION_VALUE,RoundingMode.HALF_UP) ; static volatile BigDecimal ji = new BigDecimal("1").setScale(PRECISION_VALUE,RoundingMode.HALF_UP) ; private static double calculate_improve2_byBigDecimal( int cnt ) { // 建议用法,使用字符串格式构造,不会损失精度: BigDecimal num = new BigDecimal("2.222222"); final int y_begin = 3 ; sum = B0 ; class Thread1 extends Thread{ boolean ifFinished = false ; //收集分母的数组数据 @Override public void run() { super.run(); for( int i = 1 ; i li2.put( i , new LinkedHashMap() ) ; } for( int j = 1 ; j li2.get(i).put( j , y_begin ) ; }else{ li2.get(i).put( j , li2.get(i).get(j-1) + 2 ) ; } } //计算并汇总结果,然后显示 //计算,然后从 map中 移除输入的变量,节省内存 ji = B1 ; Integer key = i ; LinkedHashMap inner_map = li2.get(i) ; if( inner_map!=null && inner_map.size() > 0 ){ // 比较数量,看是否可以开始运算了。不能在数据尚未准备完毕的时候就开始计算 assert( key!=null && key == inner_map.size()) ; for( Map.Entry entry2 : inner_map.entrySet() ) { try{ ji = ji .multiply ( new BigDecimal(entry2.getKey()+"").setScale(PRECISION_VALUE,RoundingMode.HALF_UP) .divide ( new BigDecimal(entry2.getValue()+"") , 10 , RoundingMode.HALF_UP // 关键,不然会报错 : java.lang.ArithmeticException Non-terminating decimal expansion; no exact representable decimal result ) ); }catch (Exception e){ e.printStackTrace(); } } sum = sum.add(ji) ; if(i ptl("当前运算到"+i+"次了,当前π约等于:"+ (sum.add(B1) ).multiply(B2) ); } } ptl("\n分母\n" + li2.toString() ); ifFinished = true ; ptl( "Thread1 运行结束"); ptl("\n请输入计算次数多少次 ,为"+cnt+"的条件下,π约等于:\n"+ (sum.add(B1) ).multiply(B2) ); } } Thread1 th1 = new Thread1() ; th1.start(); return 0 ; } private static void ptl(String s) { System.out.println( s ); } }5.接下来,我们开始运行并测试,输入10000 次,查看结果:
6.大功告成! 感觉有用的伙伴点下关注或者赞嘛,谢谢了。有什么不足也欢迎大家指出。 显而易见,只要电脑性能足够好,内存够用,我们可以把运算次数设置到很大。让这个程序一直算下去,这样圆周率就会更加的精确了。要拼速度的话,我们就等未来量子计算机大展身手吧! |
CopyRight 2018-2019 实验室设备网 版权所有 |