Java, BigDecimal. Проблемы с делением - PullRequest
14 голосов
/ 25 мая 2009

Я пытаюсь рассчитать процентный «фактор». То есть, учитывая 20%, преобразовать его в 0,2 (я намерен позже умножить значения на это и получить 20% значений).

В любом случае, вопрос связан с этим фрагментом кода:

public static void main(String[] args) {
    int roundingMode = BigDecimal.ROUND_FLOOR;
    BigDecimal hundred = new BigDecimal("100");
    BigDecimal percentageFactor = null;
    BigDecimal percentage = new BigDecimal("20");
    BigDecimal value = new BigDecimal("500");
    percentageFactor = percentage.divide(hundred, roundingMode);
    float f = percentage.floatValue() / hundred.floatValue();
    f = value.floatValue() * f;
    BigDecimal aux = value.multiply(percentageFactor);
    System.out.println("factor:"+percentageFactor.toString());
    System.out.println("final falue:"+aux.toString());
    System.out.println("Float Value:"+f);       
}

Я ожидаю, что результат будет примерно таким:

factor: 0.2
final value: 100
float value: 100

но вместо percentage.divide(hundred, roundingMode); возвращается ноль, следовательно, я получаю:

factor:0
final falue:0
Float Value:100.0

Что я делаю не так? Как правильно разделить два больших знака после запятой?

Кстати, я использую BigDecimal, потому что я буду рассчитывать денежные проценты, поэтому я хочу контролировать округление.

Ответы [ 4 ]

14 голосов
/ 25 мая 2009

Я думаю, что наилучшим решением является установка требуемой шкалы при делении: в данном случае, возможно, 2.

    BigDecimal hundred = new BigDecimal(100);
    BigDecimal percentage = new BigDecimal(20);
    BigDecimal value = new BigDecimal(500);
    BigDecimal percentageFactor =
                 percentage.divide(hundred,2, BigDecimal.ROUND_HALF_UP);

    value = value.multiply(percentageFactor);
    System.out.println("final value:"+ value);

конечное значение 100,00

(При умножении используется шкала из коэффициентов (0 + 2), но ее также можно указать.)

Я бы использовал HALF_UP для учета (в моем законодательстве) или ДАЖЕ (для статистики) в режиме округления.

9 голосов
/ 25 мая 2009

Масштаб new BigDecimal("20") равен нулю, потому что там нет десятичной точки. Это означает, что ваш percentage.divide(hundred, BigDecimal.ROUND_FLOOR) будет выдавать ноль (фактически int(20/100) или 0).

Если вы действительно хотите делать дробные вещи, используйте new BigDecimal("20.00"), чтобы масштаб был установлен правильно, или используйте один из других конструкторов, чтобы установить масштаб специально.

Вот результат этого простого изменения 20 на 20.00, дополненного ошибочным указанием орфографии: -)

factor:0.20
final falue:100.00
Float Value:100.0
0 голосов
/ 25 мая 2009

float имеет только 6 цифр точности и почти никогда не является хорошим выбором, я бы посоветовал использовать вместо него double. (или BigDecimal может быть лучше в некоторых случаях)

0 голосов
/ 25 мая 2009

вы, вероятно, хотите использовать ROUND_UP в качестве режима округления

...