Я пытаюсь выяснить как к раунду денежная сумма вверх к ближайшим 5 центам. Следующие шоу мои ожидаемые результаты
1.03 => 1.05
1.051 => 1.10
1.05 => 1.05
1.900001 => 1.10
Мне нужен результат, чтобы быть, имеют точность 2 (как показано выше).
Следуя совету ниже, лучшее, которое я мог сделать, является этим
BigDecimal amount = new BigDecimal(990.49)
// To round to the nearest .05, multiply by 20, round to the nearest integer, then divide by 20
def result = new BigDecimal(Math.ceil(amount.doubleValue() * 20) / 20)
result.setScale(2, RoundingMode.HALF_UP)
Я не убежден, что это на 100% кошерное - я обеспокоен, что точность могла быть потеряна, когда преобразование в и от удваивается. Однако лучше, чтобы я придумал до сих пор, и, кажется, работает.
Вы можете использовать простоту, чтобы сделать это.
double amount = 990.49;
double rounded = ((double) (long) (amount * 20 + 0.5)) / 20;
Редактировать: для отрицательных чисел вам нужно вычитать 0,5
Я бы попробую умножить на 20, округляя до ближайшего целого числа, а затем разделив на 20. Это хак, но должен получить правильный ответ.
На основании вашего редактирования еще одно возможное решение было бы:
BigDecimal twenty = new BigDecimal(20);
BigDecimal amount = new BigDecimal(990.49)
// To round to the nearest .05, multiply by 20, round to the nearest integer, then divide by 20
BigDecimal result = new BigDecimal(amount.multiply(twenty)
.add(new BigDecimal("0.5"))
.toBigInteger()).divide(twenty);
Это имеет преимущество, чтобы быть гарантированным не потерять точность, хотя это может быть более медленнее, конечно, ...
И журнал Scala Test:
scala> var twenty = new java.math.BigDecimal(20)
twenty: java.math.BigDecimal = 20
scala> var amount = new java.math.BigDecimal("990.49");
amount: java.math.BigDecimal = 990.49
scala> new BigDecimal(amount.multiply(twenty).add(new BigDecimal("0.5")).toBigInteger()).divide(twenty)
res31: java.math.BigDecimal = 990.5
TOM имеет правильную идею, но вам необходимо использовать более широкие методы, поскольку вы якобы используете BigDecimal, потому что ваши значения не поддаются примитивным типом данных. Что-то вроде:
BigDecimal num = new BigDecimal(0.23);
BigDecimal twenty = new BigDecimal(20);
//Might want to use RoundingMode.UP instead,
//depending on desired behavior for negative values of num.
BigDecimal numTimesTwenty = num.multiply(twenty, new MathContext(0, RoundingMode.CEILING));
BigDecimal numRoundedUpToNearestFiveCents
= numTimesTwenty.divide(twenty, new MathContext(2, RoundingMode.UNNECESSARY));