BigDecimal символы / скобки - PullRequest
       10

BigDecimal символы / скобки

4 голосов
/ 20 ноября 2011

Я пытаюсь заставить BigDecimal использовать символы (например, вместо Decimal.multiply, делать Decimal *), потому что в эту проблему вовлечена массовая скобка.

Не могли бы вы, ребята, сказать мне, есть ли способ использовать символы в BigDecimal без преобразования их в Double или что-то еще? Или вы можете преобразовать т в формате, как термин?

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.

Ответы [ 4 ]

4 голосов
/ 20 ноября 2011

Нет. К сожалению Java не поддерживает перегрузку операторов. У вас нет выбора, кроме как использовать эти методы на BigDecimal.

3 голосов
/ 20 ноября 2011

Неа.Поскольку в 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;
    }

}
2 голосов
/ 20 ноября 2011

Вы можете написать простой синтаксический анализатор для построения выражения и затем оценить его, используя Rhino или другой механизм сценариев, доступный в коде Java.

1 голос
/ 21 ноября 2011

Вместо того, чтобы сначала инвертировать 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.

...