java/kotlin:格式double/int,总位数固定
java/kotlin: format double/int with fixed total digits
我尝试四处搜索,但找不到针对此问题的完整解决方案:
我想格式化一个 Int
以便总位数始终为 3。举几个例子:
1000000 -> 1,00m
678945 -> 678k
65432 -> 65,4k
5437 -> 5,43k
数字绝不能小于 1000 或大于 10 亿,因此其他情况并不重要
这是我最接近的:
@JvmStatic
fun formatPointsTop3(points: Int?): String {
if (points == null) return ""
val formatter = NumberFormat.getInstance(Locale.ITALIAN)
val mathContext = MathContext(3, RoundingMode.DOWN)
return when {
points < 1000 -> {
"$points"
}
points < 1000000 -> {
val bigDecimal = BigDecimal(points / 1000.0, mathContext)
"${formatter.format(bigDecimal)}k"
}
else -> {
val bigDecimal = BigDecimal(points / 1000000.0, mathContext)
"${formatter.format(bigDecimal)}m"
}
}
}
除了输出 1m(我想要 1.00m)的 1000000 之外,这在大多数情况下都可以正常工作。添加 formatter.minimumFractionDigits = 2
为所有数字添加小数。
有没有办法在不直接在字符串上做奇怪的事情的情况下实现这一点?
应该有。首先,弄清楚你想要如何呈现它,这似乎你对每个 log(n) 的确切方式有不同的看法(例如,输入中有多少位数字)。对于 7 位数字,您想要呈现值,divided by 100 万,具有 2 个小数位。对于 8 位数字,您需要值 div 百万和 1 个小数,等等。这将是很多代码,也许字符串操作更简单。
我最终这样做了:
fun formatPointsTop3(points: Int?): String {
if (points == null) return ""
if (points == 0) return "0"
val maxNumberOfDigits = 3
val multiplierExponent = log(points.toDouble(), 1000.0).toInt()
val bigPoints = BigDecimal(points)
val bigDivider = BigDecimal(1000).pow(multiplierExponent)
val reducedPoints = bigPoints.divide(bigDivider)
val intPart = reducedPoints.toBigInteger().toInt()
val decimalPart = reducedPoints.subtract(BigDecimal(intPart)).toDouble()
val numberOfDecimals = maxNumberOfDigits - (log10(intPart.toDouble()).toInt() + 1)
var formattedString = "$intPart"
if (numberOfDecimals > 0) {
val multiplier = 10.0.pow(numberOfDecimals)
val formatter = NumberFormat.getIntegerInstance()
formatter.minimumIntegerDigits = numberOfDecimals
formatter.maximumIntegerDigits = numberOfDecimals
val multiplied = (decimalPart * multiplier).toInt()
formattedString += ",${formatter.format(multiplied)}"
}
formattedString += when (multiplierExponent) {
0 -> ""
1 -> "k"
2 -> "m"
3 -> "b"
else -> "" //this is not possible as max int is 2 billions
}
return formattedString
}
它很丑,但它看起来比字符串操作好
我尝试四处搜索,但找不到针对此问题的完整解决方案:
我想格式化一个 Int
以便总位数始终为 3。举几个例子:
1000000 -> 1,00m
678945 -> 678k
65432 -> 65,4k
5437 -> 5,43k
数字绝不能小于 1000 或大于 10 亿,因此其他情况并不重要
这是我最接近的:
@JvmStatic
fun formatPointsTop3(points: Int?): String {
if (points == null) return ""
val formatter = NumberFormat.getInstance(Locale.ITALIAN)
val mathContext = MathContext(3, RoundingMode.DOWN)
return when {
points < 1000 -> {
"$points"
}
points < 1000000 -> {
val bigDecimal = BigDecimal(points / 1000.0, mathContext)
"${formatter.format(bigDecimal)}k"
}
else -> {
val bigDecimal = BigDecimal(points / 1000000.0, mathContext)
"${formatter.format(bigDecimal)}m"
}
}
}
除了输出 1m(我想要 1.00m)的 1000000 之外,这在大多数情况下都可以正常工作。添加 formatter.minimumFractionDigits = 2
为所有数字添加小数。
有没有办法在不直接在字符串上做奇怪的事情的情况下实现这一点?
应该有。首先,弄清楚你想要如何呈现它,这似乎你对每个 log(n) 的确切方式有不同的看法(例如,输入中有多少位数字)。对于 7 位数字,您想要呈现值,divided by 100 万,具有 2 个小数位。对于 8 位数字,您需要值 div 百万和 1 个小数,等等。这将是很多代码,也许字符串操作更简单。
我最终这样做了:
fun formatPointsTop3(points: Int?): String {
if (points == null) return ""
if (points == 0) return "0"
val maxNumberOfDigits = 3
val multiplierExponent = log(points.toDouble(), 1000.0).toInt()
val bigPoints = BigDecimal(points)
val bigDivider = BigDecimal(1000).pow(multiplierExponent)
val reducedPoints = bigPoints.divide(bigDivider)
val intPart = reducedPoints.toBigInteger().toInt()
val decimalPart = reducedPoints.subtract(BigDecimal(intPart)).toDouble()
val numberOfDecimals = maxNumberOfDigits - (log10(intPart.toDouble()).toInt() + 1)
var formattedString = "$intPart"
if (numberOfDecimals > 0) {
val multiplier = 10.0.pow(numberOfDecimals)
val formatter = NumberFormat.getIntegerInstance()
formatter.minimumIntegerDigits = numberOfDecimals
formatter.maximumIntegerDigits = numberOfDecimals
val multiplied = (decimalPart * multiplier).toInt()
formattedString += ",${formatter.format(multiplied)}"
}
formattedString += when (multiplierExponent) {
0 -> ""
1 -> "k"
2 -> "m"
3 -> "b"
else -> "" //this is not possible as max int is 2 billions
}
return formattedString
}
它很丑,但它看起来比字符串操作好