Reputation: 395
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
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
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
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