如何用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<Integer,LinkedHashMap<Integer,Integer> > 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 <= cnt   ; i ++  ){
                    if( li2.get(i) == null ){
                        li2.put( i , new LinkedHashMap< >() )  ;
                    }
                    for( int j = 1 ; j <= i  ; j++){
                        if( j == 1 ){
                            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<Integer,Integer>  inner_map =  li2.get(i)  ;
                            if( inner_map!=null && inner_map.size() > 0 ){
                                // 比较数量,看是否可以开始运算了。不能在数据尚未准备完毕的时候就开始计算
                                assert( key!=null && key == inner_map.size()) ;
                                for( Map.Entry<Integer,Integer> 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<cnt){
                                    li2.remove(i) ; //移除,释放内存
                                }
                            }
                    if( i% 100 == 0 ){
                        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 次,查看结果:

在这里插入图片描述
这里只算了300次,结果是:
3.141592653474797574000800718750900160885326539264258915787386802030980132047213023667953865876484049707460356783856474199565848668187338432750250111013094708707465022609505046533027730533672511800984756773864431272032800078005059834738294210323423627666458396783387900576738007015269888682634239952125923540310317692097663944359860070593459776080821877036421928351198673939807632564142007655604873678069540799907788604636077615560856982437763158487293822941759772952776595107515497601436052889571792394814598772826315638116821965989052734505504876777520015556039370115874420858974735770835788827046322812594834513019880133059192213379989858137907146747051769207379732518252263875359036912965261684464289764810899338265478870237441902624894842309598325258582612379617957615327290030673922169222540315006892315098441541409816709247178506027854175030098070569055869963071240946785251545626411904116893885212462071960385758436652588477881388131714913912610893133765071234330361632065956320637886980074912753542950668829345027008522618326976577699601940232894200704339758244597851535729257941976823837498668816059299791007572394097935450357053867520673830724430512898342124406587513849246462030328376678285217695196062370604983308291633873131483840221162847144205119112520703478023383980873334562493376016718557580410888253348596352917717700093201332383842657109418209044553018550500679217949386375261867804422454029082587534709498228197063716144263024115396131307190552127511616325730649281558431171000831210285432040488910241977927065421747598903287428070739784496010708941560658483235861843026609692479059943372372994416375171477088152356936783924681249270422601405929324806005009334117980035992625531319200419298606361057853330334391268620534887404398464299489897143870254507907967987650744001799250182802486149768750130940928268882370442757907159318574437635687784483573174222523194923349915524587706770009601333276031487927478393715824346738474104305092660114728799295062945042759369388485083088996995694864766108499439689116787107496516668894177465476760850357189635560991791317284724439176793065158078696455630148356662737691476755280674489441886233487664209071489023922933695927852855430790877078853978690822633658713903508031424627348208447555609010527543200025304567309892727354503051712975226496290443302164770361015995364041163648384804602670481329886364848780335543757178349712741887674907669761279333200277548595654878292343388689274660835523801918991484149253732166609091525170848626956074085960531361931444384714254041827161872712848307385091472122247751472003632646424668682739051033028474081426498937578094408555791979000112361584051349536656609270802728216466575562184599019097223818542989486418285478610918796847559214291418151100010733727655871080874095316186237431230144474897703353615721196724498028236734429880673882475206670544227458253471704507089361463019809719823293242404765696

6.大功告成!
感觉有用的伙伴点下关注或者赞嘛,谢谢了。有什么不足也欢迎大家指出。

显而易见,只要电脑性能足够好,内存够用,我们可以把运算次数设置到很大。让这个程序一直算下去,这样圆周率就会更加的精确了。要拼速度的话,我们就等未来量子计算机大展身手吧!

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值