2011-11-20 237 views
4

我试图强制BigDecimal使用符号(例如,而不是Decimal.multiply,做十进制*),因为大括号涉及此问题。BigDecimal符号/括号

你们可以告诉我,如果有方法使用BigDecimal上的符号而不将其转换为Double或其他东西?或者你可以把t转换成像term这样的格式吗?

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)))))); 

我试过记录了很多次,花了近6小时,试图找出在我得到错误的BigDecimal的。

回答

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

编号Unfortunately Java不支持运算符重载。您别无选择,只能在BigDecimal上使用这些方法。

+0

如何减少参与括号的数量?是通过为BigDecimal方法制作一个方法来解决这个问题的唯一方法吗? – Muhatashim

+0

@Peter你可以将你的长公式分成更小的块,并用单独的命令处理它们。它会增加行数,但它会让你的代码更具可读性。 – Laf

+0

@彼得:拉夫说了什么。恐怕只有这样才能做到这一点。 – missingfaktor

2

您可以编写一个简单的解析器来构建表达式,然后使用Rhino或Java代码中提供的其他脚本引擎对其进行评估。

1

而不是首先反转f1,你可以简单地通过放置它最后的表达。

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

您确定您需要BigDecimal提供的准确性。即您需要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 

如果你需要的精度大于15个的数字,你需要的BigDecimal。但是如果你想简化你的代码并且不需要那么高的精度,我只需要使用double