V.Lorz
V.Lorz

Reputation: 395

How to convert a double to string, and back, in a culture independent mode?

I need to convert double precision floating point values (Double) to string and back in a format that should be culture independent.

What is the idiomatic way of doing it Kotlin?

BR.

Upvotes: 1

Views: 69

Answers (3)

V.Lorz
V.Lorz

Reputation: 395

To the extent of what I could check and test, the answers provided by Klitos Kyriacou and Uddyan Semwal are both useful and correct, so this is just for sharing another finding.

Regarding the implementations of toString() and toDouble(), I've just learned they are based on specifications given by standards, IEEE 754 and ECMAScript, and provide consistent interoperation for JVM, Kotlin Multiplatform and Kotlin Native. So, to my opinion, this is the way to go.

Using DecimalFormat(...).format(...) and NumberFormat.getInstance(...).parse(...) seems to be more appropriated when it is necessary to use a specific locale or regional configuration, or when it is a requirement to make numbering formats configurable. It could do the job in my use case, but would add an overhead when compared to using the default implementations for toDouble() and toString().

Upvotes: 2

Klitos Kyriacou
Klitos Kyriacou

Reputation: 11652

Assuming you are using Kotlin/JVM, the toString methods are not Locale-dependent; therefore you can just use number.toString() and string.toDouble(). The result will be the same as the original number, even though some numbers cannot be exactly represented as decimal. This is because the toString() function will create a string that has just enough decimal precision to uniquely identify the value's Double representation.

Example:

val d = 0.1 + 0.2

// toString() gives 0.30000000000000004. This is correct and not Kotlin's fault.
// See https://0.30000000000000004.com for explanation
val s = d.toString()
println(s)

val d2 = s.toDouble()
println(d == d2)  // prints "true"

Upvotes: 2

Uddyan Semwal
Uddyan Semwal

Reputation: 752

import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.util.*

fun doubleToString(value: Double): String {
    val format = DecimalFormat("#.####################") // Pattern with precision to your liking
    format.decimalFormatSymbols = DecimalFormatSymbols(Locale.US) // Ensure culture independence (e.g., dot as decimal separator)
    return format.format(value)
}

fun stringToDouble(value: String): Double {
    val format = DecimalFormat("#.####################") // Use the same pattern to ensure correct parsing
    format.decimalFormatSymbols = DecimalFormatSymbols(Locale.US) // Consistent locale
    return format.parse(value).toDouble()
}

fun main() {
    val doubleValue = 12345.6789
    val stringValue = doubleToString(doubleValue)
    println("Double to String: $stringValue") // 12345.6789

    val parsedValue = stringToDouble(stringValue)
    println("String to Double: $parsedValue") // 12345.6789
}

Upvotes: 0

Related Questions