Skip to content

Instantly share code, notes, and snippets.

@liorgonnen
Created December 17, 2024 08:29
Show Gist options
  • Save liorgonnen/d4da823d54d6288b3aab984ae1ac25e9 to your computer and use it in GitHub Desktop.
Save liorgonnen/d4da823d54d6288b3aab984ae1ac25e9 to your computer and use it in GitHub Desktop.
Equivalent to DecimalFormat("#.######") but thread-safe and faster
package com.gonnen.util
import kotlin.math.pow
private const val PRECISION = 6
private val SCALE_FACTOR = 10.0.pow(PRECISION).toLong()
/**
* Equivalent to DecimalFormat("#.######") but thread-safe and faster.
*/
fun fastNumberToString(number: Double) = StringBuilder().apply {
if (number.isNaN()) {
append(number.toString())
return@apply
}
require(!(number * SCALE_FACTOR + 0.5 > Long.MAX_VALUE)) { "Number too large: $number" }
val absValue = if (number < 0) -number else number
var scaled = (absValue * SCALE_FACTOR + 0.5).toLong()
if (scaled == 0L) {
append('0')
return@apply
}
var digitsAdded = 0
do {
val digit = scaled % 10
if (isNotEmpty() || digit != 0L) append('0' + digit.toInt())
digitsAdded++
if (digitsAdded == PRECISION && isNotEmpty()) append('.')
scaled /= 10L
} while (digitsAdded <= PRECISION || scaled != 0L)
if (number < 0) append('-')
}.reverse().toString()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment