首先,我们知道计算圆周率最精确的方式:
π = 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.大功告成!
感觉有用的伙伴点下关注或者赞嘛,谢谢了。有什么不足也欢迎大家指出。
显而易见,只要电脑性能足够好,内存够用,我们可以把运算次数设置到很大。让这个程序一直算下去,这样圆周率就会更加的精确了。要拼速度的话,我们就等未来量子计算机大展身手吧!