# Convert double to string to double

How can I convert a double to a string using the country’s formatting and back again to a string?

For example if the number is Pi and I’m in France, I want the conversion to string to produce “3,14” with rounding of 2 decimal places and then convert “3,14” back to the rounded floating point value of 3.14 if I’m still in France but produce an error if I’m in the United States.

Likewise, if the string was “3,141” in the United states, it should parse to 3141.0, since commas in the United States are used as numeric separators.

If this isn’t possible, how much I18N floating point support is there in Kotlin and where can I read about it? Thanks.

Take a look to JVM DecimalFormat

yeah, decimal formatter helps
and one more thing - string formatting is for showing numbers or parsing numbers from user native input, not for saving numbers
in both cases you can create numberformat from current user locale and parse or format with it
if it’s not jdk - read about your locale-dependend formatting, anyway try to avoid hardcoded symbols and create your formatters from user locale settings
if you for some reasons still need to save your number as text - convert it to single invariant locale for it

Could you explain more? I have user entered floating point numbers that I need to save as text. In other words, if the user entered: “1,345.6700” in the United States, I need to convert the number to 1345.67 to process. However, if my app is closed, I have to save and restore exactly what they entered and not restore it to “1345.67”.

If they enter “1.234.56”, I convert that to NaN but still restore “1.234.56”

Is DecimalFormat from Java what I want to use? It is unclear if DecimalFormat converts both to and from strings/doubles.

Thanks

Why not simply save the original user input, instead of “converting back” to it?

``````import java.io.File
import java.nio.ByteBuffer
import java.text.NumberFormat
import java.util.*

fun main() {
val locale = Locale.getDefault()
val nf = NumberFormat.getInstance() // current locale formatter
val userPi = nf.format(Math.PI) // user input

println("current locale: \${locale.displayName}")
println("user input in current locale: \$userPi")

val parsedPi = nf.parse(userPi).toDouble() // now you have double

println("parsed input: \$parsedPi")

val binaryStorage = BinaryStorage("./storage.bin")
val textStorage = TextStorage("./storage.txt")

//you save parsed input in bin
binaryStorage.save(parsedPi)

//or in text
textStorage.save(parsedPi)

val bin = binaryStorage.load() // you have double
val txt = textStorage.load() // and here too

//now you can show localized value to user
println("localized output for user: \${nf.format(bin)}")
}

interface Storage {
val filepath: String
fun save(value: Double)
}

class BinaryStorage(override val filepath: String) : Storage {
private val file = File(filepath)

override fun save(value: Double) = with(file) {
if (exists())
delete()

createNewFile()
writeBytes(value.toByteArray())
}

private fun Double.toByteArray() =
ByteBuffer.allocate(Long.SIZE_BYTES).putDouble(this).array()

private fun ByteArray.toDouble() =
ByteBuffer.allocate(size).put(this).apply { position(0) }.double
}

class TextStorage(override val filepath: String) : Storage {
private val file = File(filepath)
private val formatter =
NumberFormat.getInstance(Locale.ENGLISH) // invariant locale for saving

override fun save(value: Double) = with(file) {
if (exists())
delete()

createNewFile()
writeText(formatter.format(value))
}