2011-11-20 3 views
4

이 문제와 관련된 대량 괄호 때문에 BigDecimal에서 기호 (예 : Decimal.multiply 대신 Decimal *, 대신 Decimal *)를 사용하도록하고 있습니다.BigDecimal symbols/parenthesis

BigDecimal에서 Double을 변환하지 않고 기호를 사용하는 방법이 있다면 말해 줄 수 있습니까? 아니면 t를 용어와 같은 형식으로 변환 할 수 있습니까? 형식으로

double t = ((1.00/f1) * ((((4.00/(ak1 + 1.00)) - (2.00/(ak1 + 4.00))) - (1.00/(ak1 + 5.00))) - (1/(ak1 + 6.00)))); 

term = ((one.divide(f,mc)).multiply(((((four.divide((ak.add(one)),mc)).subtract((two.divide((ak.add(four)),mc)))).subtract((one.divide((ak.add(five)),mc)))).subtract((one.divide((ak.add(six)),mc)))))); 

처럼 그것을 시간을 많이 기록했는데, 나는 BigDecimal의 문제군요 곳을 내려고 거의 6 시간 보냈어요.

답변

3

아니요. Java에는 연산자 오버로딩이 없으므로

자신을 좀더 단순하게 만들려면 수식을 부품에 기입하고 복잡하거나 반복되는 비트를 여러 번 식별하십시오. 이 부분으로 계산을 해체하고 계산 된 합계를 얻는 데 도움이되는 도우미 방법을 작성하십시오. 전체 계산을 부분으로 작성하면 각 부분을 더 쉽게 테스트 할 수 있습니다.

예 :

import static java.math.BigDecimal.ONE; 

public class Sum { 

    private static final TWO = new BigDecimal("2"); 
    private static final FOUR = new BigDecimal("4"); 
    private static final FIVE = new BigDecimal("5"); 
    private static final SIX = new BigDecimal("6"); 

    private BigDecimal f; 
    private BigDecimal ak; 

    private MathContext mc; 

    public Sum(BigDecimal f, BigDecimal ak, MathContext mc) { 
     this.f = f; 
     this.ak = ak; 
     this.mc = mc; 
    } 

    public BigDecimal calculate() { 

     return inverse(f).multiply(
      firstSubtractRest(
       xOverYPlusZ(FOUR, ak, ONE), 
       xOverYPlusZ(TWO, ak, FOUR), 
       xOverYPlusZ(ONE, ak, FIVE), 
       xOverYPlusZ(ONE, ak, SIX), 

      )); 

    } 

    private BigDecimal inverse(BigDecimal x) { 
     return ONE.divide(x, mc); 
    } 

    /* returns x/(y + z) */ 
    private BigDecimal xOverYPlusZ(BigDecimal x, BigDecimal y, BigDecimal z) { 
     BigDecimal divisor = y.add(z); 
     return x.divide(divisor, mc); 
    } 

    private BigDecimal firstSubtractRest(BigDecimal... values) { 
     BigDecimal value = values[0]; 
     for (int i = 1; i < values.length; i++) { 
      value = value.subtract(values[i]); 
     } 
     return value; 
    } 

} 
+0

고마워, 내게 많은 도움이되었지만 내 괄호는 여전히 틀렸다. 그러나이 문제를 해결하는 방법은 괄호를 수정하는 것이 더 쉽습니다. – Muhatashim

4

No. Unfortunately Java는 연산자 오버로딩을 지원하지 않습니다. 이 방법을 BigDecimal에 사용할 수 밖에 없습니다.

+0

그것에 관련된 괄호의 양을 줄이는 것은 어떻습니까? BigDecimal 메서드에 대한 메서드를 만들어 문제를 해결할 수있는 유일한 방법은 무엇입니까? – Muhatashim

+0

@Peter 긴 수식을 작은 덩어리로 나누고 별도의 명령으로 처리 할 수 ​​있습니다. 줄 수는 늘어나지 만 코드가 더 읽기 쉽습니다. – Laf

+0

@ 피터 : Laf은 말했습니다. 나는 그것이 이것에 관해 갈 수있는 유일한 방법 인 것이 아닌가 걱정된다. – missingfaktor

2

간단한 구문 분석기를 작성하여 표현식을 작성한 다음 Rhino 또는 Java 코드 내에서 사용 가능한 다른 스크립팅 엔진을 사용하여 평가할 수 있습니다.

1

f1을 먼저 반전하는 대신 간단히 표현식을 마지막으로 배치하여 표현할 수 있습니다.

double t = (4/(ak1 + 1) - 2/(ak1 + 4) - 1/(ak1 + 5) - 1/(ak1 + 6))/f1; 

BigDecimal에서 제공하는 정확성이 필요하십니까? 즉 15 자리 이상의 정밀도가 필요합니다. 당신이 정확도 15 개 이상의 자리가 필요한 경우

double f1 = 1; 
double ak1 = 1; 

double t = (4/(ak1 + 1) - 2/(ak1 + 4) - 1/(ak1 + 5) - 1/(ak1 + 6))/f1; 

System.out.println(t); 

System.out.println(new Sum(BigDecimal.ONE, BigDecimal.ONE, MathContext.DECIMAL64).calculate()); 
System.out.println(new Sum(BigDecimal.ONE, BigDecimal.ONE, MathContext.DECIMAL128).calculate()); 

인쇄

1.2904761904761906 
1.2904761904761904 
1.2904761904761904761904761904761904 

, 당신의 BigDecimal이 필요합니다. 그러나 코드를 간소화하고 많은 정밀도가 필요하지 않은 경우 double을 사용합니다.