Home > Software design >  How do you remove extra zeros at the end of a decimal in Kotlin?
How do you remove extra zeros at the end of a decimal in Kotlin?

Time:06-13

I'm creating a function that rounds large numbers over 1,000 and then returns a string of that rounded number. For example, "2374293" would return as "2.37m"
However, my I dont want any extra zeros at the end of decimals like "25.00" or "100.50".

For Example:

What I want:

 Input  ->  Output

"11000" -> "11k"
"11400" -> "11.4k"

What I get:

 Input  ->  Output

"11000" -> "11.00k"
"11400" -> "11.40k"

How would I remove these zeros and decimal point(if it's a whole number) when needed?

Here is my code currently:

    private fun roundBigNumb(numb: Long): String {
    val newNumb = numb.toDouble()
    return when {
        numb in 1000..999994 -> {
            BigDecimal(newNumb/1000).setScale(2, RoundingMode.HALF_EVEN).toString() "k"
        }
        numb in 999995..999999 -> {
            "999.99k"
        }
        numb in 1000000..999994999 -> {
            BigDecimal(newNumb/1000000).setScale(2, RoundingMode.HALF_EVEN).toString() "m"
        }

        numb in 999995000..999999999 -> {
            "999.99m"
        }

        numb in 1000000000..999994999999 -> {
            BigDecimal(newNumb/1000000000).setScale(2, RoundingMode.HALF_EVEN).toString() "b"
        }

        numb in 999995000000..999999999999 -> {                    
            "999.99b"
        }

        numb in 1000000000000..999994999999999 -> {
            BigDecimal(newNumb/1000000000000).setScale(2, RoundingMode.HALF_EVEN).toString() "t"
        }

        numb in 999995000000000..999999999999999 -> {
            "999.99t"
        }

        numb >= 1000000000000000 -> "∞"

        else -> numb.toString()
    }
}

CodePudding user response:

Once you have converted the number to a string with up to 2 decimal places (as you are doing), you can use dropLastWhile to drop trailing zeros and decimal places.

Here is an example

fun prettyFormat(input: Double): String {
    if( input == 0.0 ) return "0"
    
    val prefix = if( input < 0 ) "-" else ""
    val num = abs(input)

    // figure out what group of suffixes we are in and scale the number
    val pow = floor(log10(num)/3).roundToInt()
    val base = num / 10.0.pow(pow * 3)

    // Using consistent rounding behavior, always rounding down since you want
    // 999999999 to show as 999.99M and not 1B
    val roundedDown = floor(base*100)/100.0

    // Convert the number to a string with up to 2 decimal places
    var baseStr = BigDecimal(roundedDown).setScale(2, RoundingMode.HALF_EVEN).toString()

    // Drop trailing zeros, then drop any trailing '.' if present
    baseStr = baseStr.dropLastWhile { it == '0' }.dropLastWhile { it == '.' }

    val suffixes = listOf("","k","M","B","T")

    return when {
        pow < suffixes.size -> "$prefix$baseStr${suffixes[pow]}"
        else -> "${prefix}infty"
    }
}

This produces

11411.0   = 11.41k
11000.0   = 11k
9.99996E8 = 999.99M
12.4      = 12.4
0.0       = 0
-11400.0  = -11.4k

If you don't care about zero or negative numbers it can be simplified a bit.

CodePudding user response:

import java.math.BigDecimal
import java.math.RoundingMode.HALF_EVEN

fun roundBigNumber(number: Long): String {
  fun calc(divisor: Long) = BigDecimal(number.toDouble() / divisor)
    .setScale(2, HALF_EVEN)
    .toString()
    .dropLastWhile { it == '0' }
    .dropLastWhile { it == '.' }
  return when {
    number in 1000..999994                     -> calc(1000)   "k"
    number in 999995..999999                   -> "999.99k"
    number in 1000000..999994999               -> calc(1000000)   "m"
    number in 999995000..999999999             -> "999.99m"
    number in 1000000000..999994999999         -> calc(1000000000)   "b"
    number in 999995000000..999999999999       -> "999.99b"
    number in 1000000000000..999994999999999   -> calc(1000000000000)   "t"
    number in 999995000000000..999999999999999 -> "999.99t"
    number >= 1000000000000000                 -> "∞"
    else                                       -> number.toString()
  }
}
  • Related