Kotlin 是否有 BigDecimal setPrecision 实用方法?
Does Kotlin have a BigDecimal setPrecision utility method?
我在某处读到 Java 的决定委员会决定 BigDecimal
上的 setPrecision
方法是愚蠢的,因为它已经有 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)
}
}
这还没有涵盖所有情况。
如果您要寻找的只是更简单(更简洁)的代码版本,那么您可以通过计算规模(16 - log10(value)
或 11
,以较大者为准来简化它):
return value.setScale((int) Math.max(11, 16 - Math.log10(value.doubleValue())),
RoundingMode.HALF_UP);
这只是一行,因为您的比例需要根据精确度进行精确更改:
fun BigDecimal.setPrecision(newPrecision: Int) = setScale(scale() + (newPrecision - precision()), RoundingMode.HALF_UP)
或者(更明显,但效率较低):
fun BigDecimal.setPrecision(newPrecision: Int) = BigDecimal(toPlainString(), MathContext(newPrecision, RoundingMode.HALF_UP))
我在某处读到 Java 的决定委员会决定 BigDecimal
上的 setPrecision
方法是愚蠢的,因为它已经有 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)
}
}
这还没有涵盖所有情况。
如果您要寻找的只是更简单(更简洁)的代码版本,那么您可以通过计算规模(16 - log10(value)
或 11
,以较大者为准来简化它):
return value.setScale((int) Math.max(11, 16 - Math.log10(value.doubleValue())),
RoundingMode.HALF_UP);
这只是一行,因为您的比例需要根据精确度进行精确更改:
fun BigDecimal.setPrecision(newPrecision: Int) = setScale(scale() + (newPrecision - precision()), RoundingMode.HALF_UP)
或者(更明显,但效率较低):
fun BigDecimal.setPrecision(newPrecision: Int) = BigDecimal(toPlainString(), MathContext(newPrecision, RoundingMode.HALF_UP))