diff --git a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt index ec90f715f..6aebccbaa 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt @@ -10,41 +10,48 @@ class DisplayedNumber( ) { private val isPositive: Boolean private val digits: List - private val exponent: Int + private val positionalExponent: Int init { fun prepareNonZero(v: Double): Pair> { val w = abs(v) - val exponent = ceil(log10(w)).toInt() - val shift = nbSignificantDigits - exponent - val digits = ArrayList() + val positionalExponent = ceil(log10(w)).toInt() + val shift = nbSignificantDigits - positionalExponent + val reversedDigits = ArrayList() var u = floor(w * (10.0.pow(shift))).toInt() while (u > 0) { - digits.add(u.mod(10)) + reversedDigits.add(u.mod(10)) u /= 10 } - - if (digits.take(nbSignificantDigits).all { it == 9 }) { - return exponent to listOf(1,) + listOf(0).replicate(nbSignificantDigits - 1).flatten() + val digits = reversedDigits.reversed() + + if (digits.tail().take(nbSignificantDigits - 1).all { it == 9 }) { + val hd = digits[0] + if (hd == 9) { + val zeros = listOf(0).replicate(nbSignificantDigits - 2).flatten() + return positionalExponent to listOf(1, 0) + zeros + } + val zeros = listOf(0).replicate(nbSignificantDigits - 1).flatten() + return positionalExponent to listOf(hd + 1) + zeros } - return exponent to digits.reversed() + return positionalExponent to digits } if (value == 0.0) { isPositive = true - exponent = 1 + positionalExponent = 1 digits = IntRange(1, nbSignificantDigits).map { 0 } } else { val (e, d) = prepareNonZero(value) isPositive = value > 0.0 - exponent = e + positionalExponent = e digits = d } } fun getExponent(): Int { - return exponent + return positionalExponent } fun getDigits(): List { @@ -57,13 +64,13 @@ class DisplayedNumber( } private fun renderPowerOf10(): String { - return when (exponent) { + return when (positionalExponent) { -2 -> "0.01" -1 -> "0.1" 0 -> "1" 1 -> "10" 2 -> "100" - else -> "1E$exponent" + else -> "1E$positionalExponent" }.let { if (isPositive) it else "-$it" } @@ -79,17 +86,30 @@ class DisplayedNumber( } val midpoint = when { - exponent < 0 -> 1 - exponent <= nbSignificantDigits -> exponent + positionalExponent <= -nbSignificantDigits + 1 -> 1 + -nbSignificantDigits + 1 < positionalExponent + && positionalExponent < nbSignificantDigits -> positionalExponent + else -> nbSignificantDigits } - val displayedExponent = exponent - midpoint + val displayedExponent = when { + -nbSignificantDigits + 1 < positionalExponent + && positionalExponent < nbSignificantDigits -> 0 - val head = digits.subList(0, midpoint).joinToString("") - .ifEmpty { "0" } - val tail = digits.subList(midpoint, nbSignificantDigits) - .dropLastWhile { it == 0 } - .joinToString("") + else -> positionalExponent - midpoint + } + + val head = when { + midpoint <= 0 -> emptyList() + else -> digits.subList(0, midpoint) + }.joinToString("").ifEmpty { "0" } + val tail = when { + midpoint <= 0 -> { + val prefix = listOf(0).replicate(-midpoint).flatten() + prefix + digits.take(nbSignificantDigits) + } + else -> digits.subList(midpoint, nbSignificantDigits) + }.dropLastWhile { it == 0 }.joinToString("") val sign = if (isPositive) "" else "-" val e = if (displayedExponent == 0) "" else "E$displayedExponent" diff --git a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt index 5fd5b65d1..85e6a1c41 100644 --- a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt +++ b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt @@ -37,11 +37,19 @@ class DisplayedNumberTest { 99.9 to "100", 999.0 to "1E3", - 0.0123 to "1.23E-2", + 0.003999 to "4E-3", + 0.04999 to "0.05", + 0.5999 to "0.6", + 6.999 to "7", + 79.90 to "80", + 899.9 to "900", + 999.0 to "1E3", + + 0.00123 to "1.23E-3", + 0.0123 to "0.0123", 0.123 to "0.123", 1.2345 to "1.23", 12345.123 to "123E2", - 0.00123 to "1.23E-3", -0.0 to "0", -0.0001 to "-1E-4", @@ -52,7 +60,7 @@ class DisplayedNumberTest { -100.0 to "-100", -1000.0 to "-1E3", - -0.0123 to "-1.23E-2", + -0.0123 to "-0.0123", -0.123 to "-0.123", -1.2345 to "-1.23", -12345.123 to "-123E2",