class Expression implements Parcelable {

    @NonNull
    BigDecimal evaluate(boolean priority, int scale, RoundingMode roundingMode) {
        if (numbers.size() != operators.size() + 1) {
            throw new IllegalStateException("Numbers and operators aren't balanced.");
        }

        if (numbers.size() == 1) return numbers.get(0);

        List<BigDecimal> nbs = new ArrayList<>(numbers);
        List<Operator> ops = new ArrayList<>(operators);

        if (priority) {
            // Evaluate products and quotients
            int i = 0;
            while (i < ops.size()) {
                Operator op = ops.get(i);
                if (op == Operator.MULTIPLY) {
                    ops.remove(i);
                    BigDecimal n1 = nbs.get(i);
                    BigDecimal n2 = nbs.remove(i + 1);
                    nbs.set(i, n1.multiply(n2));
                } else if (op == Operator.DIVIDE) {
                    ops.remove(i);
                    BigDecimal n1 = nbs.get(i);
                    BigDecimal n2 = nbs.remove(i + 1);
                    nbs.set(i, n1.divide(n2, scale, roundingMode));
                } else {
                    i++;
                }
            }
        }

        // Evaluate the rest
        while (!ops.isEmpty()) {
            Operator op = ops.remove(0);
            BigDecimal n1 = nbs.get(0);
            BigDecimal n2 = nbs.remove(1);
            if (op == Operator.ADD) {
                nbs.set(0, n1.add(n2));
            } else if (op == Operator.SUBTRACT) {
                nbs.set(0, n1.subtract(n2));
            } else if (op == Operator.MULTIPLY) {
                nbs.set(0, n1.multiply(n2));
            } else {
                nbs.set(0, n1.divide(n2, scale, roundingMode));
            }
        }

        return nbs.remove(0).stripTrailingZeros();
    }

}

class ExpressionTest {

    @Test
    public void longExpression() {

        Expression expr = new Expression();
        expr.numbers.add(new BigDecimal("-1"));
        expr.operators.add(Expression.Operator.DIVIDE);
        expr.numbers.add(new BigDecimal("6"));
        expr.operators.add(Expression.Operator.ADD);
        expr.numbers.add(new BigDecimal("5"));
        expr.operators.add(Expression.Operator.MULTIPLY);
        expr.numbers.add(new BigDecimal("12"));
        expr.operators.add(Expression.Operator.DIVIDE);
        expr.numbers.add(new BigDecimal("3"));
        expr.operators.add(Expression.Operator.DIVIDE);
        expr.numbers.add(new BigDecimal("8"));
        expr.operators.add(Expression.Operator.SUBTRACT);
        expr.numbers.add(new BigDecimal("-10"));

        BigDecimal result1 = expr.evaluate(false, 8, RoundingMode.HALF_UP);
        assertEquals(result1, new BigDecimal("12.41666667"));

        BigDecimal result2 = expr.evaluate(true, 8, RoundingMode.HALF_UP);
        assertEquals(result2, new BigDecimal("12.33333333"));
    }

}