2013-11-27 4 views
2

BBS 알고리즘을 사용하여 Pi 수를 계산하는 솔루션을 찾았습니다. 그러나 문제가 발생했습니다. 이중 변수를 사용하면 정밀도가 누락됩니다. 그것을 고칠 수있는 제안이 있습니까?Java 큰 배수에서 사용하는 방법?

public class Pi { 
    public static void main(String[] args) { 
     int n = 5; 

     for (int k = 0; k < n; k++) { 
      int a0 = (int) Math.pow(16, k); 

      double a1 = (double) 4/(8 * k + 1); 
      double a2 = (double) 2/(8 * k + 4); 
      double a3 = (double) 1/(8 * k + 5); 
      double a4 = (double) 1/(8 * k + 6); 

      double a5 = a1 - a2 - a3 - a4; 
      double a6 = (double) 1/a0; 
      double elem = a5 * a6; 

      System.out.println(new BigDecimal(elem)); 
     } 
    } 
} 
+4

'bigdecimal'질문에 태그를 추가했습니다. 너 해봤 어? – EJP

답변

2

BigDecimal의 정밀도가 필요한 경우 모든 계산에 사용해야합니다. 결과를 double에서 BigDecimal으로 변환하는 것만으로는 충분하지 않습니다. 정확도가 그만큼 떨어 졌기 때문입니다.

당신은 BigDecimal 클래스의 대응 방법에 전화와 연산자를 BigDecimal에 모든 aX 변수를 변환하고, 대체해야합니다

BigDecimal pi = BigDecimal.ZERO; 
for (int k = 0; k < n; k++) { 
    BigDecimal a0 = new BigDecimal(16).pow(k); 
    BigDecimal a1 = new BigDecimal(4).divide(new BigDecimal(8*k+1), 20, RoundingMode.HALF_UP); 
    BigDecimal a2 = new BigDecimal(2).divide(new BigDecimal(8*k+4), 20, RoundingMode.HALF_UP); 
    BigDecimal a3 = new BigDecimal(1).divide(new BigDecimal(8*k+5), 20, RoundingMode.HALF_UP); 
    BigDecimal a4 = new BigDecimal(1).divide(new BigDecimal(8*k+6), 20, RoundingMode.HALF_UP); 
    BigDecimal a5 = a1.subtract(a2).subtract(a3).subtract(a4); 
    BigDecimal a6 = BigDecimal.ONE.divide(a0, 20, RoundingMode.HALF_UP); 
    pi.add(a5.multiply(a6)); 
    System.out.println(pi); 
} 

Demo on ideone.

+1

@Alex 런타임 오류를 수정하고 알고리즘에서 누락 된 코드를 추가하여 데이터를 최종 파이 수에 누적합니다. 나는 임의의 정밀도 20을 골랐다. 필요에 맞게 변경할 수 있습니다. – dasblinkenlight

+0

감사합니다. 그것은 잘 작동합니다. – Alex

3

문제는 당신이 때문에 필연적으로 정확성을 잃고, 계산 자체가 동안 두 배를 사용하고 있다는 것입니다 :

여기 내 코드입니다. 예, 마지막에 BigDecimal을 사용하고 있지만 데이터를 두 배로 놓아서 이미 데이터를 삭제 한 후에 만 ​​사용합니다.

해결 방법은 계산시 ANY 지점에서 복식을 사용하지 않는 것입니다. 매 단계마다 BigDecimal을 사용하십시오.

은유를 사용하는 방법 : 수영장의 물을 유리에 붓고 유리를 수영장 안으로 쏟아 부어 예상하는 것입니다. 대부분의 물이 유리에 들어 가지 않고 땅에 쏟아져 나오지 않기 때문에 아닙니다.