2

I am trying to print multiple doubles with different decimal points, I have search for a while but I cannot find the exact solution for my need.

Let me explain it as an example, so there are a few double variables here:

  1. 1.23
  2. 0.330
  3. 1.00
  4. 1.001

The result I want:

  1. 1.23
  2. 0.33 (unwanted 0 removed)
  3. 1 (unwanted 0 removed)
  4. 1.001

Is there any pre-developed syntax for this or do I have to make the algo myself?

My current solution:

fun Double.roundToLastDecimal(): Number {
    val num = this.toString().toDouble()
    return if (num % 1 == 0.0) {
        num.toInt()
    } else {
        num
    }
}

4 Answers4

5

Double.toString() already does most of this for you - it just retains as many digits as necessary to distinguish the number from other doubles, so it'll strip the trailing zeroes.

The only issue is wanting 1.0 represented as 1, since that's technically an integer representation, not a double. You can write a function to take care of that case though:

// or a val with a get() to make the string representation a property
fun Double.roundToString() = when {
    toInt().toDouble() == this -> toInt()
    else -> this
}.toString()

Just FYI, if the number's small enough (less than 10¯³) toString() will produce scientific notation instead of listing all the digits with leading zeroes. If you want to handle those, you'll probably have to work with format strings, decide how much precision you want, etc.

Here's a way you can do that, with up to 10 digits of precision, and any trailing zeroes removed (and the decimal point itself, if it ends up at the end):

fun Double.roundToString() = "%.10f".format(this).trimEnd('0').trimEnd('.')

or using a regex if you're into that

fun Double.roundToString() = "%.10f".format(this).replace(Regex("\\.*0+$"), "")
cactustictacs
  • 17,935
  • 2
  • 14
  • 25
2

I would use a simple extension function for Double, maybe like this:

fun Double.printMinimalRepresentation() {
    // check if the decimal places equal zero
    if (this % 1 > 0.0) {
        // if not, just print the number
        println(this)
    } else {
        // otherwise convert to Int and print
        println(this.toInt())
    }
}

Example values in a main function:

fun main() {
    var a: Double = 1.23
    var b: Double = 0.330
    var c: Double = 1.00
    var d: Double = 1.001

    a.printMinimalRepresentation()
    b.printMinimalRepresentation()
    c.printMinimalRepresentation()
    d.printMinimalRepresentation()
}

This prints

1.23
0.33
1
1.001

Please note that the conversion toInt() not only removes the unwanted zero but the obviously unwantet dot as well.

deHaar
  • 17,687
  • 10
  • 38
  • 51
  • 1
    Yes we can simply convert the decimals into string and then do one last validation to check whether if it is int. From your idea in the comment, I was updating my question to add my current solution and the next second found our solution to be the same. Thanks! – William Tan Dec 08 '22 at 11:12
  • 1
    I decided to delete my comment and put an answer… However, it's the idea that matters ^^. Good to see you read the comment and came to (nearly) the same solution. I just printed the results because your question starts with *I am trying to print…*. – deHaar Dec 08 '22 at 11:14
0

val value = 0.330

val res = (value * 100.0).roundToInt() / 100.0

-1

Have you tried using the round function from the kotlin.math package?

import kotlin.math.round
QANew
  • 52
  • 8