Есть ли у Kotlin метод утилиты BigDecimal setPrecision? - PullRequest
2 голосов
/ 21 января 2020

Я где-то читал, что решающий комитет Java решил, что метод setPrecision для BigDecimal будет глупым, поскольку он уже имеет setScale.

Что еще глупее иметь У пользователей API есть такие методы в своем коде:

private fun getBigDecimalWith16DigitPrecision(value: BigDecimal): BigDecimal {
    return when {
        value < BigDecimal.ONE -> value.setScale(16, RoundingMode.HALF_UP)
        value < BigDecimal(10) -> value.setScale(15, RoundingMode.HALF_UP)
        value < BigDecimal(100) -> value.setScale(14, RoundingMode.HALF_UP)
        value < BigDecimal(1000) -> value.setScale(13, RoundingMode.HALF_UP)
        value < BigDecimal(10000) -> value.setScale(12, RoundingMode.HALF_UP)
        else -> value.setScale(11, RoundingMode.HALF_UP)
    }
}

, который даже не охватывает все случаи.

Ответы [ 2 ]

1 голос
/ 21 января 2020

Это всего лишь одна строка, поскольку ваша шкала должна меняться точно так же, как и точность:

fun BigDecimal.setPrecision(newPrecision: Int) = setScale(scale() + (newPrecision - precision()), RoundingMode.HALF_UP)

Или, альтернативно (более очевидно, но менее эффективно):

fun BigDecimal.setPrecision(newPrecision: Int) = BigDecimal(toPlainString(), MathContext(newPrecision, RoundingMode.HALF_UP))
1 голос
/ 21 января 2020

Если все, что вам нужно, это более простая (более краткая) версия вашего кода, то вы можете упростить ее, рассчитав масштаб (16 - log10(value) или 11, в зависимости от того, что больше):

return value.setScale((int) Math.max(11, 16 - Math.log10(value.doubleValue())),
                      RoundingMode.HALF_UP);
...