Change Duration.toString(unit, decimals) formatting

- switch to scientific notation when value is too big (greater than 1e14)
- allow at most 12 decimals, larger values are coerced to 12
- use scientific format with exactly two decimals in mantissa in JVM
This commit is contained in:
Ilya Gorbunov
2019-06-17 04:46:24 +03:00
parent 5cf7c7e5bf
commit a5b7c270ae
3 changed files with 13 additions and 8 deletions
@@ -34,4 +34,4 @@ internal actual fun formatUpToDecimals(value: Double, decimals: Int): String =
private val scientificFormat = ThreadLocal<DecimalFormat>()
internal actual fun formatScientific(value: Double): String =
scientificFormat.getOrSet { DecimalFormat("0E0", rootFormatSymbols).apply { maximumFractionDigits = 2 } }.format(value)
scientificFormat.getOrSet { DecimalFormat("0E0", rootFormatSymbols).apply { minimumFractionDigits = 2 } }.format(value)
+5 -1
View File
@@ -279,7 +279,11 @@ public inline class Duration internal constructor(internal val value: Double) :
public fun toString(unit: DurationUnit, decimals: Int = 0): String {
require(decimals >= 0) { "decimals must be not negative, but was $decimals" }
if (isInfinite()) return value.toString()
return formatToExactDecimals(toDouble(unit), decimals) + unit.shortName()
val number = toDouble(unit)
return when {
abs(number) < 1e14 -> formatToExactDecimals(number, decimals.coerceAtMost(12))
else -> formatScientific(number)
} + unit.shortName()
}
+7 -6
View File
@@ -308,12 +308,13 @@ class DurationTest {
d = (d - 516.nanoseconds) / 17
test(DurationUnit.NANOSECONDS, "0ns", "0.0ns", "0.02ns", "0.020ns", "0.0202ns")
testOnJvm {
d = Double.MAX_VALUE.nanoseconds
// are such long representations ok?
test(DurationUnit.DAYS, "20806633505350875${"0".repeat(278)}d")
test(DurationUnit.NANOSECONDS, "17976931348623157${"0".repeat(292)}ns")
}
d = Double.MAX_VALUE.nanoseconds
test(DurationUnit.DAYS, "2.08e294d")
test(DurationUnit.NANOSECONDS, "1.80e308ns")
assertEquals("0.500000000000s", 0.5.seconds.toString(DurationUnit.SECONDS, 100))
assertEquals("99999000000000.000000000000ns", 99_999.seconds.toString(DurationUnit.NANOSECONDS, 15))
assertEquals("1.00e14ns", 100_000.seconds.toString(DurationUnit.NANOSECONDS, 9))
d = Duration.INFINITE
test(DurationUnit.DAYS, "Infinity", "Infinity")