Apakah Kotlin memiliki metode utilitas BigDecimal setPrecision?

Saya membaca bahwa panitia penentu Java memutuskan bahwa metode setPrecision pada BigDecimal akan menjadi bodoh, karena sudah memiliki setScale.

Yang lebih bodoh lagi adalah pengguna API memiliki metode seperti ini dalam kode mereka:

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)
    }
}

Yang bahkan tidak mencakup semua kasus.


person Torben Vesterager    schedule 21.01.2020    source sumber
comment
Menurut saya, komite Java berhutang kepada saya untuk ~10 baris kode tersebut, yang sekarang harus saya kurangi dari total no. garis yang dapat saya pertahankan secara efektif   -  person Torben Vesterager    schedule 21.01.2020
comment
Akan seperti apa jadinya jika BigDecimal memiliki metode setPrecision? Tidak mengerti.   -  person ernest_k    schedule 21.01.2020
comment
Saya kira ini adalah contoh yang cukup langka.   -  person Dorian Gray    schedule 21.01.2020
comment
@ernest_k Misal. BigDecimal("33.23").setPrecision(5) == BigDecimal("33.230"), BigDecimal("33.23").setPrecision(2) == BigDecimal("33").   -  person Alexey Romanov    schedule 21.01.2020


Jawaban (2)


Itu hanya satu baris, karena skala Anda perlu diubah sama persis dengan presisi:

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

Atau alternatifnya (lebih jelas, tetapi kurang efisien):

fun BigDecimal.setPrecision(newPrecision: Int) = BigDecimal(toPlainString(), MathContext(newPrecision, RoundingMode.HALF_UP))
person Alexey Romanov    schedule 21.01.2020

Jika yang Anda cari hanyalah versi kode yang lebih sederhana (lebih ringkas), Anda dapat menyederhanakannya dengan menghitung skala (16 - log10(value), atau 11, mana saja yang lebih besar):

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