From e093c648456d821eb721f5c675e970fd541caed6 Mon Sep 17 00:00:00 2001 From: Peva Blanchard Date: Sat, 22 Jul 2023 00:05:20 +0200 Subject: [PATCH 1/7] utility class to display a numeric value --- .../ui/toolwindow/DisplayedNumber.kt | 77 +++++++++++++++++++ .../ui/toolwindow/InventoryTableModel.kt | 4 +- .../ui/toolwindow/DisplayedNumberTest.kt | 43 +++++++++++ 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt create mode 100644 src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt diff --git a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt new file mode 100644 index 000000000..17e7bb879 --- /dev/null +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt @@ -0,0 +1,77 @@ +package ch.kleis.lcaplugin.ui.toolwindow + +import kotlin.math.* + +class DisplayedNumber( + private val value: Double, + private val nbSignificantDigits: Int = 3 +) { + private val isPositive: Boolean + private val digits: List + private val exponent: Int + + init { + fun prepareNonZero(v: Double): Pair> { + val w = abs(v) + val exponent = ceil(log10(w)).toInt() + val shift = nbSignificantDigits - exponent + val digits = ArrayList() + var u = floor(w * (10.0.pow(shift))).toInt() + while (u > 0) { + digits.add(u.mod(10)) + u /= 10 + } + return exponent to digits.reversed() + } + + if (value == 0.0) { + isPositive = true + exponent = 1 + digits = IntRange(1, nbSignificantDigits).map { 0 } + } else { + val (e, d) = prepareNonZero(value) + isPositive = value > 0.0 + exponent = e + digits = d + } + } + + fun getExponent(): Int { + return exponent + } + + fun getDigits(): List { + return digits + } + + override fun toString(): String { + if (value == 0.0) { + return "0" + } + if (value == 1.0) { + return "1" + } + if (value == -1.0) { + return "-1" + } + + val midpoint = when { + exponent < 0 -> 1 + exponent <= nbSignificantDigits -> exponent + else -> nbSignificantDigits + } + val displayedExponent = exponent - midpoint + + val head = digits.subList(0, midpoint).joinToString("") + .ifEmpty { "0" } + val tail = digits.subList(midpoint, nbSignificantDigits) + .dropLastWhile { it == 0 } + .joinToString("") + + val sign = if (isPositive) "" else "-" + val e = if (displayedExponent == 0) "" else "E$displayedExponent" + return if (tail.isEmpty()) "$sign$head$e" else "$sign${head}.$tail$e" + } +} + + diff --git a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/InventoryTableModel.kt b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/InventoryTableModel.kt index ebc36d30b..8417742fb 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/InventoryTableModel.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/InventoryTableModel.kt @@ -59,7 +59,7 @@ class InventoryTableModel( val quantity = inventory.supply.quantityOf(outputProduct) if (columnIndex == 1) { - return "${quantity.amount}" + return DisplayedNumber(quantity.amount).toString() } if (columnIndex == 2) { return "${quantity.unit.symbol}" @@ -67,7 +67,7 @@ class InventoryTableModel( val inputProduct = sortedControllablePorts[columnIndex - 3] val ratio = inventory.impactFactors.valueRatio(outputProduct, inputProduct).amount - return quantity.amount * ratio + return DisplayedNumber(quantity.amount * ratio).toString() } override fun setValueAt(aValue: Any?, rowIndex: Int, columnIndex: Int) { diff --git a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt new file mode 100644 index 000000000..81940c0ec --- /dev/null +++ b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt @@ -0,0 +1,43 @@ +package ch.kleis.lcaplugin.ui.toolwindow + +import org.junit.Test +import kotlin.test.assertEquals + +class DisplayedNumberTest { + @Test + fun test_displayedNumber() { + // given + val value = 1.2345 + + // when + val actual = DisplayedNumber(value, nbSignificantDigits = 3) + + // then + assertEquals(1, actual.getExponent()) + assertEquals(listOf(1, 2, 3), actual.getDigits()) + } + + @Test + fun test_toString() { + listOf( + 0.0 to "0", + 0.0123 to "1.23E-2", + 0.123 to "0.123", + 1.0 to "1", + 1.2345 to "1.23", + 12345.123 to "123E2", + 0.00123 to "1.23E-3", + + -0.0 to "0", + -0.0123 to "-1.23E-2", + -0.123 to "-0.123", + -1.0 to "-1", + -1.2345 to "-1.23", + -12345.123 to "-123E2", + -0.00123 to "-1.23E-3", + ).forEach { + val actual = DisplayedNumber(it.first).toString() + assertEquals(it.second, actual) + } + } +} From dd0f277bd4a81c19a6dd7f28331191fb937e6f6c Mon Sep 17 00:00:00 2001 From: Peva Blanchard Date: Sat, 22 Jul 2023 01:04:45 +0200 Subject: [PATCH 2/7] fix tests --- .../ui/toolwindow/DisplayedNumber.kt | 27 +++++++++++++---- .../ui/toolwindow/DisplayedNumberTest.kt | 30 ++++++++++++++----- .../toolwindow/LcaProcessAssessResultTest.kt | 2 +- 3 files changed, 45 insertions(+), 14 deletions(-) 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 17e7bb879..1eb32c2f2 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt @@ -1,5 +1,6 @@ package ch.kleis.lcaplugin.ui.toolwindow +import com.intellij.util.containers.tail import kotlin.math.* class DisplayedNumber( @@ -44,15 +45,31 @@ class DisplayedNumber( return digits } + private fun isPowerOf10(): Boolean { + return digits[0] == 1 + && digits.tail().all { it == 0 } + } + + private fun renderPowerOf10(): String { + return when (exponent) { + -2 -> "0.01" + -1 -> "0.1" + 0 -> "1" + 1 -> "10" + 2 -> "100" + else -> "1E$exponent" + }.let { + if (isPositive) it else "-$it" + } + } + override fun toString(): String { if (value == 0.0) { return "0" } - if (value == 1.0) { - return "1" - } - if (value == -1.0) { - return "-1" + + if (isPowerOf10()) { + return renderPowerOf10() } val midpoint = when { 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 81940c0ec..7439549d1 100644 --- a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt +++ b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt @@ -21,20 +21,34 @@ class DisplayedNumberTest { fun test_toString() { listOf( 0.0 to "0", + 0.0001 to "1E-4", + 0.001 to "1E-3", + 0.01 to "0.01", + 1.0 to "1", + 10.0 to "10", + 100.0 to "100", + 1000.0 to "1E3", + 0.0123 to "1.23E-2", 0.123 to "0.123", - 1.0 to "1", 1.2345 to "1.23", 12345.123 to "123E2", 0.00123 to "1.23E-3", - -0.0 to "0", - -0.0123 to "-1.23E-2", - -0.123 to "-0.123", - -1.0 to "-1", - -1.2345 to "-1.23", - -12345.123 to "-123E2", - -0.00123 to "-1.23E-3", + -0.0 to "0", + -0.0001 to "-1E-4", + -0.001 to "-1E-3", + -0.01 to "-0.01", + -1.0 to "-1", + -10.0 to "-10", + -100.0 to "-100", + -1000.0 to "-1E3", + + -0.0123 to "-1.23E-2", + -0.123 to "-0.123", + -1.2345 to "-1.23", + -12345.123 to "-123E2", + -0.00123 to "-1.23E-3", ).forEach { val actual = DisplayedNumber(it.first).toString() assertEquals(it.second, actual) diff --git a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/LcaProcessAssessResultTest.kt b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/LcaProcessAssessResultTest.kt index f84b76414..23e5a929f 100644 --- a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/LcaProcessAssessResultTest.kt +++ b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/LcaProcessAssessResultTest.kt @@ -68,7 +68,7 @@ class LcaProcessAssessResultTest { assertThat(html, containsString("carrot")) val text = result.getTransferData(DataFlavor("text/plain;class=java.lang.String")) as String assertThat(text, containsString("item\tquantity\tunit\t[Resource] propanol(air) [kg]")) - assertThat(text, containsString("\ncarrot\t1.0\tg\t0.001\t")) + assertThat(text, containsString("\ncarrot\t1\tg\t1E-3\t")) } } From 7a3147059d7e3c7be151f5a4f9c742792166d5c4 Mon Sep 17 00:00:00 2001 From: Peva Blanchard Date: Sat, 22 Jul 2023 01:21:29 +0200 Subject: [PATCH 3/7] simplify when trailing 9s --- .../ui/toolwindow/DisplayedNumber.kt | 6 ++++ .../ui/toolwindow/DisplayedNumberTest.kt | 36 +++++++++++-------- 2 files changed, 28 insertions(+), 14 deletions(-) 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 1eb32c2f2..ec90f715f 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt @@ -1,5 +1,6 @@ package ch.kleis.lcaplugin.ui.toolwindow +import arrow.core.replicate import com.intellij.util.containers.tail import kotlin.math.* @@ -22,6 +23,11 @@ class DisplayedNumber( digits.add(u.mod(10)) u /= 10 } + + if (digits.take(nbSignificantDigits).all { it == 9 }) { + return exponent to listOf(1,) + listOf(0).replicate(nbSignificantDigits - 1).flatten() + } + return exponent to digits.reversed() } 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 7439549d1..5fd5b65d1 100644 --- a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt +++ b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt @@ -29,26 +29,34 @@ class DisplayedNumberTest { 100.0 to "100", 1000.0 to "1E3", + 0.000999 to "1E-3", + 0.00999 to "0.01", + 0.0999 to "0.1", + 0.999 to "1", + 9.99 to "10", + 99.9 to "100", + 999.0 to "1E3", + 0.0123 to "1.23E-2", 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", - -0.001 to "-1E-3", - -0.01 to "-0.01", - -1.0 to "-1", - -10.0 to "-10", - -100.0 to "-100", - -1000.0 to "-1E3", - - -0.0123 to "-1.23E-2", - -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", + -0.001 to "-1E-3", + -0.01 to "-0.01", + -1.0 to "-1", + -10.0 to "-10", + -100.0 to "-100", + -1000.0 to "-1E3", + + -0.0123 to "-1.23E-2", + -0.123 to "-0.123", + -1.2345 to "-1.23", + -12345.123 to "-123E2", + -0.00123 to "-1.23E-3", ).forEach { val actual = DisplayedNumber(it.first).toString() assertEquals(it.second, actual) From b78225d547b59e36bcff04488e119f49654f0053 Mon Sep 17 00:00:00 2001 From: Peva Blanchard Date: Sat, 22 Jul 2023 08:14:00 +0200 Subject: [PATCH 4/7] more cases --- .../ui/toolwindow/DisplayedNumber.kt | 64 ++++++++++++------- .../ui/toolwindow/DisplayedNumberTest.kt | 14 +++- 2 files changed, 53 insertions(+), 25 deletions(-) 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", From 949d7506954eb29ad26a5ce0913f4c9002471355 Mon Sep 17 00:00:00 2001 From: Peva Blanchard Date: Sat, 22 Jul 2023 09:54:17 +0200 Subject: [PATCH 5/7] hopefully it works now --- .../ui/toolwindow/DisplayedNumber.kt | 83 +++++------ .../ui/toolwindow/DisplayedNumberTest.kt | 134 ++++++++++++++++-- 2 files changed, 166 insertions(+), 51 deletions(-) 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 6aebccbaa..13827a18a 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt @@ -1,5 +1,6 @@ package ch.kleis.lcaplugin.ui.toolwindow +import arrow.core.flatten import arrow.core.replicate import com.intellij.util.containers.tail import kotlin.math.* @@ -15,7 +16,10 @@ class DisplayedNumber( init { fun prepareNonZero(v: Double): Pair> { val w = abs(v) - val positionalExponent = ceil(log10(w)).toInt() + val e = ceil(log10(w)).toInt() + val positionalExponent = + if (w == 10.0.pow(e)) e + else e - 1 val shift = nbSignificantDigits - positionalExponent val reversedDigits = ArrayList() var u = floor(w * (10.0.pow(shift))).toInt() @@ -23,13 +27,13 @@ class DisplayedNumber( reversedDigits.add(u.mod(10)) u /= 10 } - val digits = reversedDigits.reversed() + val digits = reversedDigits.reversed().take(nbSignificantDigits) 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 + return positionalExponent + 1 to listOf(1, 0) + zeros } val zeros = listOf(0).replicate(nbSignificantDigits - 1).flatten() return positionalExponent to listOf(hd + 1) + zeros @@ -40,7 +44,7 @@ class DisplayedNumber( if (value == 0.0) { isPositive = true - positionalExponent = 1 + positionalExponent = 0 digits = IntRange(1, nbSignificantDigits).map { 0 } } else { val (e, d) = prepareNonZero(value) @@ -50,7 +54,7 @@ class DisplayedNumber( } } - fun getExponent(): Int { + fun getPositionalExponent(): Int { return positionalExponent } @@ -77,43 +81,40 @@ class DisplayedNumber( } override fun toString(): String { - if (value == 0.0) { - return "0" - } - - if (isPowerOf10()) { - return renderPowerOf10() - } - - val midpoint = when { - positionalExponent <= -nbSignificantDigits + 1 -> 1 - -nbSignificantDigits + 1 < positionalExponent - && positionalExponent < nbSignificantDigits -> positionalExponent - - else -> nbSignificantDigits - } - val displayedExponent = when { - -nbSignificantDigits + 1 < positionalExponent - && positionalExponent < nbSignificantDigits -> 0 - - 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) + return when { + positionalExponent in -2 .. -1 -> { + val hd = listOf(0).replicate(-positionalExponent-1).flatten() + .joinToString("") + .let { "0.$it" } + val tl = digits.take(nbSignificantDigits - positionalExponent + 1) + .dropLastWhile { it == 0 } + .joinToString("") + val sign = if (isPositive) "" else "-" + "$sign$hd$tl" } - else -> digits.subList(midpoint, nbSignificantDigits) - }.dropLastWhile { it == 0 }.joinToString("") - - val sign = if (isPositive) "" else "-" - val e = if (displayedExponent == 0) "" else "E$displayedExponent" - return if (tail.isEmpty()) "$sign$head$e" else "$sign${head}.$tail$e" + positionalExponent in 0..2 -> { + val midpoint = min(positionalExponent + 1, nbSignificantDigits) + val hd = digits.subList(0, midpoint) + .joinToString("") + val tl = digits.subList(midpoint, nbSignificantDigits) + .dropLastWhile { it == 0 } + .joinToString("") + .let { if (it.isEmpty()) "" else ".$it"} + val sign = if (isPositive) "" else "-" + "$sign$hd$tl" + } + else -> { + val hd = digits.subList(0, 1) + .joinToString("") + val tl = digits.subList(1, nbSignificantDigits) + .dropLastWhile { it == 0 } + .joinToString("") + .let { if (it.isEmpty()) "" else ".$it"} + val sign = if (isPositive) "" else "-" + val e = "E$positionalExponent" + "$sign$hd$tl$e" + } + } } } 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 85e6a1c41..d240c9905 100644 --- a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt +++ b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt @@ -5,16 +5,119 @@ import kotlin.test.assertEquals class DisplayedNumberTest { @Test - fun test_displayedNumber() { - // given - val value = 1.2345 + fun test_positive_displayedNumber() { + listOf( + 0.0012345 to -3 to "123", + 0.012345 to -2 to "123", + 0.12345 to -1 to "123", + 1.2345 to 0 to "123", + 12.345 to 1 to "123", + 123.45 to 2 to "123", + 1234.5 to 3 to "123", + 12345.0 to 4 to "123", + + 0.0 to 0 to "000", + 0.0001 to -4 to "100", + 0.001 to -3 to "100", + 0.01 to -2 to "100", + 0.1 to -1 to "100", + 1.0 to 0 to "100", + 10.0 to 1 to "100", + 100.0 to 2 to "100", + 1000.0 to 3 to "100", + + 0.000999 to -3 to "100", + 0.00999 to -2 to "100", + 0.0999 to -1 to "100", + 0.999 to 0 to "100", + 9.99 to 1 to "100", + 99.9 to 2 to "100", + 999.0 to 3 to "100", + + 0.001001 to -3 to "100", + 0.01001 to -2 to "100", + 0.1001 to -1 to "100", + 1.001 to 0 to "100", + 10.01 to 1 to "100", + 100.1 to 2 to "100", + 1001.0 to 3 to "100", + + 0.0002999 to -4 to "300", + 0.003999 to -3 to "400", + 0.04999 to -2 to "500", + 0.5999 to -1 to "600", + 6.999 to 0 to "700", + 79.90 to 1 to "800", + 899.9 to 2 to "900", + ).forEach { + val value = it.first.first + val expectedPositionalExponent = it.first.second + val expectedDigits = it.second + + val actual = DisplayedNumber(value) + val actualPositionalExponent = actual.getPositionalExponent() + val actualDigits = actual.getDigits().joinToString("") + + assertEquals(expectedPositionalExponent to expectedDigits, actualPositionalExponent to actualDigits, "value = $value") + } + } - // when - val actual = DisplayedNumber(value, nbSignificantDigits = 3) + @Test + fun test_negative_displayedNumber() { + listOf( + 0.0012345 to -3 to "123", + 0.012345 to -2 to "123", + 0.12345 to -1 to "123", + 1.2345 to 0 to "123", + 12.345 to 1 to "123", + 123.45 to 2 to "123", + 1234.5 to 3 to "123", + 12345.0 to 4 to "123", + + 0.0 to 0 to "000", + 0.0001 to -4 to "100", + 0.001 to -3 to "100", + 0.01 to -2 to "100", + 0.1 to -1 to "100", + 1.0 to 0 to "100", + 10.0 to 1 to "100", + 100.0 to 2 to "100", + 1000.0 to 3 to "100", + + 0.000999 to -3 to "100", + 0.00999 to -2 to "100", + 0.0999 to -1 to "100", + 0.999 to 0 to "100", + 9.99 to 1 to "100", + 99.9 to 2 to "100", + 999.0 to 3 to "100", + + 0.001001 to -3 to "100", + 0.01001 to -2 to "100", + 0.1001 to -1 to "100", + 1.001 to 0 to "100", + 10.01 to 1 to "100", + 100.1 to 2 to "100", + 1001.0 to 3 to "100", - // then - assertEquals(1, actual.getExponent()) - assertEquals(listOf(1, 2, 3), actual.getDigits()) + 0.0002999 to -4 to "300", + 0.003999 to -3 to "400", + 0.04999 to -2 to "500", + 0.5999 to -1 to "600", + 6.999 to 0 to "700", + 79.90 to 1 to "800", + 899.9 to 2 to "900", + ).forEach { + val value = -it.first.first + val expectedPositionalExponent = it.first.second + val expectedDigits = it.second + + val actual = DisplayedNumber(value) + val actualPositionalExponent = actual.getPositionalExponent() + val actualDigits = actual.getDigits().joinToString("") + + assertEquals(expectedPositionalExponent to expectedDigits, actualPositionalExponent to actualDigits, "value = $value") + } } @Test @@ -37,6 +140,14 @@ class DisplayedNumberTest { 99.9 to "100", 999.0 to "1E3", + 0.001001 to "1E-3", + 0.01001 to "0.01", + 0.1001 to "0.1", + 1.001 to "1", + 10.01 to "10", + 100.1 to "100", + 1001.0 to "1E3", + 0.003999 to "4E-3", 0.04999 to "0.05", 0.5999 to "0.6", @@ -49,7 +160,10 @@ class DisplayedNumberTest { 0.0123 to "0.0123", 0.123 to "0.123", 1.2345 to "1.23", - 12345.123 to "123E2", + 12.345 to "12.3", + 123.45 to "123", + 1234.5 to "1.23E3", + 12345.123 to "1.23E4", -0.0 to "0", -0.0001 to "-1E-4", @@ -63,7 +177,7 @@ class DisplayedNumberTest { -0.0123 to "-0.0123", -0.123 to "-0.123", -1.2345 to "-1.23", - -12345.123 to "-123E2", + -12345.123 to "-1.23E4", -0.00123 to "-1.23E-3", ).forEach { val actual = DisplayedNumber(it.first).toString() From 2ce21fdf932fa7b3e24a14d042e7ac5e45270a9c Mon Sep 17 00:00:00 2001 From: Peva Blanchard Date: Sun, 23 Jul 2023 11:16:07 +0200 Subject: [PATCH 6/7] JUnit4 parameterized tests --- build.gradle.kts | 2 +- .../ui/toolwindow/DisplayedNumber.kt | 91 +------ .../toolwindow/FloatingPointRepresentation.kt | 61 +++++ .../ui/toolwindow/DisplayedNumberTest.kt | 235 +++++------------- .../FloatingPointRepresentationTest.kt | 123 +++++++++ 5 files changed, 255 insertions(+), 257 deletions(-) create mode 100644 src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentation.kt create mode 100644 src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentationTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index 7c16edad9..37008b37b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -54,6 +54,7 @@ dependencies { val arrowVersion = "1.1.5" val olcaSimaproVersion = "3.0.5" val kotlinxSerializationJSONVersion = "1.5.1" + implementation(platform("io.arrow-kt:arrow-stack:$arrowVersion")) implementation("io.arrow-kt:arrow-core") implementation("io.arrow-kt:arrow-optics") @@ -91,7 +92,6 @@ qodana { showReport.set(System.getenv("QODANA_SHOW_REPORT")?.toBoolean() ?: false) } - tasks { // Set the JVM compatibility versions properties("javaVersion").let { 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 13827a18a..686023beb 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt @@ -2,88 +2,21 @@ package ch.kleis.lcaplugin.ui.toolwindow import arrow.core.flatten import arrow.core.replicate -import com.intellij.util.containers.tail import kotlin.math.* class DisplayedNumber( - private val value: Double, - private val nbSignificantDigits: Int = 3 + value: Double, + nbSignificantDigits: Int = 3 ) { - private val isPositive: Boolean - private val digits: List - private val positionalExponent: Int - - init { - fun prepareNonZero(v: Double): Pair> { - val w = abs(v) - val e = ceil(log10(w)).toInt() - val positionalExponent = - if (w == 10.0.pow(e)) e - else e - 1 - val shift = nbSignificantDigits - positionalExponent - val reversedDigits = ArrayList() - var u = floor(w * (10.0.pow(shift))).toInt() - while (u > 0) { - reversedDigits.add(u.mod(10)) - u /= 10 - } - val digits = reversedDigits.reversed().take(nbSignificantDigits) - - 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 + 1 to listOf(1, 0) + zeros - } - val zeros = listOf(0).replicate(nbSignificantDigits - 1).flatten() - return positionalExponent to listOf(hd + 1) + zeros - } - - return positionalExponent to digits - } - - if (value == 0.0) { - isPositive = true - positionalExponent = 0 - digits = IntRange(1, nbSignificantDigits).map { 0 } - } else { - val (e, d) = prepareNonZero(value) - isPositive = value > 0.0 - positionalExponent = e - digits = d - } - } - - fun getPositionalExponent(): Int { - return positionalExponent - } - - fun getDigits(): List { - return digits - } - - private fun isPowerOf10(): Boolean { - return digits[0] == 1 - && digits.tail().all { it == 0 } - } - - private fun renderPowerOf10(): String { - return when (positionalExponent) { - -2 -> "0.01" - -1 -> "0.1" - 0 -> "1" - 1 -> "10" - 2 -> "100" - else -> "1E$positionalExponent" - }.let { - if (isPositive) it else "-$it" - } - } + private val repr = FloatingPointRepresentation.of(value, nbSignificantDigits) override fun toString(): String { - return when { - positionalExponent in -2 .. -1 -> { - val hd = listOf(0).replicate(-positionalExponent-1).flatten() + val isPositive = repr.isPositive + val digits = repr.digits + val nbSignificantDigits = repr.nbSignificantDigits + return when (val positionalExponent = repr.positionalExponent) { + in -2..-1 -> { + val hd = listOf(0).replicate(-positionalExponent - 1).flatten() .joinToString("") .let { "0.$it" } val tl = digits.take(nbSignificantDigits - positionalExponent + 1) @@ -92,14 +25,14 @@ class DisplayedNumber( val sign = if (isPositive) "" else "-" "$sign$hd$tl" } - positionalExponent in 0..2 -> { + in 0..2 -> { val midpoint = min(positionalExponent + 1, nbSignificantDigits) val hd = digits.subList(0, midpoint) .joinToString("") val tl = digits.subList(midpoint, nbSignificantDigits) .dropLastWhile { it == 0 } .joinToString("") - .let { if (it.isEmpty()) "" else ".$it"} + .let { if (it.isEmpty()) "" else ".$it" } val sign = if (isPositive) "" else "-" "$sign$hd$tl" } @@ -109,7 +42,7 @@ class DisplayedNumber( val tl = digits.subList(1, nbSignificantDigits) .dropLastWhile { it == 0 } .joinToString("") - .let { if (it.isEmpty()) "" else ".$it"} + .let { if (it.isEmpty()) "" else ".$it" } val sign = if (isPositive) "" else "-" val e = "E$positionalExponent" "$sign$hd$tl$e" diff --git a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentation.kt b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentation.kt new file mode 100644 index 000000000..c199ff95f --- /dev/null +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentation.kt @@ -0,0 +1,61 @@ +package ch.kleis.lcaplugin.ui.toolwindow + +import arrow.core.flatten +import arrow.core.replicate +import com.intellij.util.containers.tail +import kotlin.math.* + +data class FloatingPointRepresentation( + val isPositive: Boolean, + val digits: List, + val positionalExponent: Int, + val nbSignificantDigits: Int, +) { + companion object { + fun of(value: Double, nbSignificantDigits: Int = 3): FloatingPointRepresentation { + if (value == 0.0) { + return FloatingPointRepresentation( + true, + IntRange(1, nbSignificantDigits).map { 0 }, + 0, + nbSignificantDigits + ) + } + val isPositive = value > 0.0 + val w = abs(value) + val e = ceil(log10(w)).toInt() + val positionalExponent = + if (w == 10.0.pow(e)) e + else e - 1 + val shift = nbSignificantDigits - positionalExponent + val reversedDigits = ArrayList() + var u = floor(w * (10.0.pow(shift))).toInt() + while (u > 0) { + reversedDigits.add(u.mod(10)) + u /= 10 + } + val digits = reversedDigits.reversed().take(nbSignificantDigits) + + 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 FloatingPointRepresentation( + isPositive, + listOf(1, 0) + zeros, + positionalExponent + 1, + nbSignificantDigits + ) + } + val zeros = listOf(0).replicate(nbSignificantDigits - 1).flatten() + return FloatingPointRepresentation( + isPositive, + listOf(hd + 1) + zeros, + positionalExponent, + nbSignificantDigits + ) + } + return FloatingPointRepresentation(isPositive, digits, positionalExponent, nbSignificantDigits) + } + } +} 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 d240c9905..f72e82d65 100644 --- a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt +++ b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt @@ -1,187 +1,68 @@ package ch.kleis.lcaplugin.ui.toolwindow +import org.junit.Assert.assertEquals import org.junit.Test -import kotlin.test.assertEquals - -class DisplayedNumberTest { - @Test - fun test_positive_displayedNumber() { - listOf( - 0.0012345 to -3 to "123", - 0.012345 to -2 to "123", - 0.12345 to -1 to "123", - 1.2345 to 0 to "123", - 12.345 to 1 to "123", - 123.45 to 2 to "123", - 1234.5 to 3 to "123", - 12345.0 to 4 to "123", - - 0.0 to 0 to "000", - 0.0001 to -4 to "100", - 0.001 to -3 to "100", - 0.01 to -2 to "100", - 0.1 to -1 to "100", - 1.0 to 0 to "100", - 10.0 to 1 to "100", - 100.0 to 2 to "100", - 1000.0 to 3 to "100", - - 0.000999 to -3 to "100", - 0.00999 to -2 to "100", - 0.0999 to -1 to "100", - 0.999 to 0 to "100", - 9.99 to 1 to "100", - 99.9 to 2 to "100", - 999.0 to 3 to "100", - - 0.001001 to -3 to "100", - 0.01001 to -2 to "100", - 0.1001 to -1 to "100", - 1.001 to 0 to "100", - 10.01 to 1 to "100", - 100.1 to 2 to "100", - 1001.0 to 3 to "100", - - 0.0002999 to -4 to "300", - 0.003999 to -3 to "400", - 0.04999 to -2 to "500", - 0.5999 to -1 to "600", - 6.999 to 0 to "700", - 79.90 to 1 to "800", - 899.9 to 2 to "900", - ).forEach { - val value = it.first.first - val expectedPositionalExponent = it.first.second - val expectedDigits = it.second - - val actual = DisplayedNumber(value) - val actualPositionalExponent = actual.getPositionalExponent() - val actualDigits = actual.getDigits().joinToString("") - - assertEquals(expectedPositionalExponent to expectedDigits, actualPositionalExponent to actualDigits, "value = $value") - } - } - - @Test - fun test_negative_displayedNumber() { - listOf( - 0.0012345 to -3 to "123", - 0.012345 to -2 to "123", - 0.12345 to -1 to "123", - 1.2345 to 0 to "123", - 12.345 to 1 to "123", - 123.45 to 2 to "123", - 1234.5 to 3 to "123", - 12345.0 to 4 to "123", - - 0.0 to 0 to "000", - 0.0001 to -4 to "100", - 0.001 to -3 to "100", - 0.01 to -2 to "100", - 0.1 to -1 to "100", - 1.0 to 0 to "100", - 10.0 to 1 to "100", - 100.0 to 2 to "100", - 1000.0 to 3 to "100", - - 0.000999 to -3 to "100", - 0.00999 to -2 to "100", - 0.0999 to -1 to "100", - 0.999 to 0 to "100", - 9.99 to 1 to "100", - 99.9 to 2 to "100", - 999.0 to 3 to "100", - - 0.001001 to -3 to "100", - 0.01001 to -2 to "100", - 0.1001 to -1 to "100", - 1.001 to 0 to "100", - 10.01 to 1 to "100", - 100.1 to 2 to "100", - 1001.0 to 3 to "100", - - 0.0002999 to -4 to "300", - 0.003999 to -3 to "400", - 0.04999 to -2 to "500", - 0.5999 to -1 to "600", - 6.999 to 0 to "700", - 79.90 to 1 to "800", - 899.9 to 2 to "900", - ).forEach { - val value = -it.first.first - val expectedPositionalExponent = it.first.second - val expectedDigits = it.second - - val actual = DisplayedNumber(value) - val actualPositionalExponent = actual.getPositionalExponent() - val actualDigits = actual.getDigits().joinToString("") - - assertEquals(expectedPositionalExponent to expectedDigits, actualPositionalExponent to actualDigits, "value = $value") +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters + + +@RunWith(Parameterized::class) +class DisplayedNumberTest( + private val value: Double, + private val expected: String, +) { + companion object { + @Parameters + @JvmStatic + fun getDisplayedStrings(): Collection> { + return listOf( + arrayOf(0.0, "0"), + arrayOf(0.0001, "1E-4"), + arrayOf(0.001, "1E-3"), + arrayOf(0.01, "0.01"), + arrayOf(0.1, "0.1"), + arrayOf(1.0, "1"), + arrayOf(10.0, "10"), + arrayOf(100.0, "100"), + arrayOf(1000.0, "1E3"), + + arrayOf(0.000999, "1E-3"), + arrayOf(0.00999, "0.01"), + arrayOf(0.0999, "0.1"), + arrayOf(0.999, "1"), + arrayOf(9.99, "10"), + arrayOf(99.9, "100"), + arrayOf(999.0, "1E3"), + + arrayOf(0.00123, "1.23E-3"), + arrayOf(0.0123, "0.0123"), + arrayOf(0.123, "0.123"), + arrayOf(1.2345, "1.23"), + arrayOf(12.345, "12.3"), + arrayOf(123.45, "123"), + arrayOf(1234.5, "1.23E3"), + arrayOf(12345.123, "1.23E4"), + + arrayOf(-0.0, "0"), + arrayOf(-0.00123, "-1.23E-3"), + arrayOf(-0.0123, "-0.0123"), + arrayOf(-0.123, "-0.123"), + arrayOf(-1.2345, "-1.23"), + arrayOf(-12.345, "-12.3"), + arrayOf(-123.45, "-123"), + arrayOf(-1234.5, "-1.23E3"), + arrayOf(-12345.123, "-1.23E4"), + ) } } @Test - fun test_toString() { - listOf( - 0.0 to "0", - 0.0001 to "1E-4", - 0.001 to "1E-3", - 0.01 to "0.01", - 1.0 to "1", - 10.0 to "10", - 100.0 to "100", - 1000.0 to "1E3", + fun run() { + // when + val actual = DisplayedNumber(value).toString() - 0.000999 to "1E-3", - 0.00999 to "0.01", - 0.0999 to "0.1", - 0.999 to "1", - 9.99 to "10", - 99.9 to "100", - 999.0 to "1E3", - - 0.001001 to "1E-3", - 0.01001 to "0.01", - 0.1001 to "0.1", - 1.001 to "1", - 10.01 to "10", - 100.1 to "100", - 1001.0 to "1E3", - - 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", - 12.345 to "12.3", - 123.45 to "123", - 1234.5 to "1.23E3", - 12345.123 to "1.23E4", - - -0.0 to "0", - -0.0001 to "-1E-4", - -0.001 to "-1E-3", - -0.01 to "-0.01", - -1.0 to "-1", - -10.0 to "-10", - -100.0 to "-100", - -1000.0 to "-1E3", - - -0.0123 to "-0.0123", - -0.123 to "-0.123", - -1.2345 to "-1.23", - -12345.123 to "-1.23E4", - -0.00123 to "-1.23E-3", - ).forEach { - val actual = DisplayedNumber(it.first).toString() - assertEquals(it.second, actual) - } + // then + assertEquals(expected, actual) } } diff --git a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentationTest.kt b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentationTest.kt new file mode 100644 index 000000000..75a6158d8 --- /dev/null +++ b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentationTest.kt @@ -0,0 +1,123 @@ +package ch.kleis.lcaplugin.ui.toolwindow + +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters +import org.junit.Test +import kotlin.test.assertEquals + +private fun digits(s: String): List { + return s.map { Integer.parseInt(it.toString()) } +} + +@RunWith(Parameterized::class) +class FloatingPointRepresentationTest( + private val value: Double, + private val expected: FloatingPointRepresentation, +) { + companion object { + + @Parameters + @JvmStatic + fun getFloatingPointRepresentationSamples(): Collection> { + return listOf( + arrayOf(0.0012345, FloatingPointRepresentation(true, digits("123"), -3, 3)), + arrayOf(0.012345, FloatingPointRepresentation(true, digits("123"), -2, 3)), + arrayOf(0.12345, FloatingPointRepresentation(true, digits("123"), -1, 3)), + arrayOf(1.2345, FloatingPointRepresentation(true, digits("123"), 0, 3)), + arrayOf(12.345, FloatingPointRepresentation(true, digits("123"), 1, 3)), + arrayOf(123.45, FloatingPointRepresentation(true, digits("123"), 2, 3)), + arrayOf(1234.5, FloatingPointRepresentation(true, digits("123"), 3, 3)), + arrayOf(12345.0, FloatingPointRepresentation(true, digits("123"), 4, 3)), + + arrayOf(0.0, FloatingPointRepresentation(true, digits("000"), 0, 3)), + arrayOf(0.0001, FloatingPointRepresentation(true, digits("100"), -4, 3)), + arrayOf(0.001, FloatingPointRepresentation(true, digits("100"), -3, 3)), + arrayOf(0.01, FloatingPointRepresentation(true, digits("100"), -2, 3)), + arrayOf(0.1, FloatingPointRepresentation(true, digits("100"), -1, 3)), + arrayOf(1.0, FloatingPointRepresentation(true, digits("100"), 0, 3)), + arrayOf(10.0, FloatingPointRepresentation(true, digits("100"), 1, 3)), + arrayOf(100.0, FloatingPointRepresentation(true, digits("100"), 2, 3)), + arrayOf(1000.0, FloatingPointRepresentation(true, digits("100"), 3, 3)), + + arrayOf(0.000999, FloatingPointRepresentation(true, digits("100"), -3, 3)), + arrayOf(0.00999, FloatingPointRepresentation(true, digits("100"), -2, 3)), + arrayOf(0.0999, FloatingPointRepresentation(true, digits("100"), -1, 3)), + arrayOf(0.999, FloatingPointRepresentation(true, digits("100"), 0, 3)), + arrayOf(9.99, FloatingPointRepresentation(true, digits("100"), 1, 3)), + arrayOf(99.9, FloatingPointRepresentation(true, digits("100"), 2, 3)), + arrayOf(999.0, FloatingPointRepresentation(true, digits("100"), 3, 3)), + + arrayOf(0.001001, FloatingPointRepresentation(true, digits("100"), -3, 3)), + arrayOf(0.01001, FloatingPointRepresentation(true, digits("100"), -2, 3)), + arrayOf(0.1001, FloatingPointRepresentation(true, digits("100"), -1, 3)), + arrayOf(1.001, FloatingPointRepresentation(true, digits("100"), 0, 3)), + arrayOf(10.01, FloatingPointRepresentation(true, digits("100"), 1, 3)), + arrayOf(100.1, FloatingPointRepresentation(true, digits("100"), 2, 3)), + arrayOf(1001.0, FloatingPointRepresentation(true, digits("100"), 3, 3)), + + arrayOf(0.0002999, FloatingPointRepresentation(true, digits("300"), -4, 3)), + arrayOf(0.003999, FloatingPointRepresentation(true, digits("400"), -3, 3)), + arrayOf(0.04999, FloatingPointRepresentation(true, digits("500"), -2, 3)), + arrayOf(0.5999, FloatingPointRepresentation(true, digits("600"), -1, 3)), + arrayOf(6.999, FloatingPointRepresentation(true, digits("700"), 0, 3)), + arrayOf(79.99, FloatingPointRepresentation(true, digits("800"), 1, 3)), + arrayOf(899.9, FloatingPointRepresentation(true, digits("900"), 2, 3)), + + arrayOf(-0.0012345, FloatingPointRepresentation(false, digits("123"), -3, 3)), + arrayOf(-0.012345, FloatingPointRepresentation(false, digits("123"), -2, 3)), + arrayOf(-0.12345, FloatingPointRepresentation(false, digits("123"), -1, 3)), + arrayOf(-1.2345, FloatingPointRepresentation(false, digits("123"), 0, 3)), + arrayOf(-12.345, FloatingPointRepresentation(false, digits("123"), 1, 3)), + arrayOf(-123.45, FloatingPointRepresentation(false, digits("123"), 2, 3)), + arrayOf(-1234.5, FloatingPointRepresentation(false, digits("123"), 3, 3)), + arrayOf(-12345.0, FloatingPointRepresentation(false, digits("123"), 4, 3)), + + arrayOf(-0.0, FloatingPointRepresentation(true, digits("000"), 0, 3)), + arrayOf(-0.0001, FloatingPointRepresentation(false, digits("100"), -4, 3)), + arrayOf(-0.001, FloatingPointRepresentation(false, digits("100"), -3, 3)), + arrayOf(-0.01, FloatingPointRepresentation(false, digits("100"), -2, 3)), + arrayOf(-0.1, FloatingPointRepresentation(false, digits("100"), -1, 3)), + arrayOf(-1.0, FloatingPointRepresentation(false, digits("100"), 0, 3)), + arrayOf(-10.0, FloatingPointRepresentation(false, digits("100"), 1, 3)), + arrayOf(-100.0, FloatingPointRepresentation(false, digits("100"), 2, 3)), + arrayOf(-1000.0, FloatingPointRepresentation(false, digits("100"), 3, 3)), + + arrayOf(-0.000999, FloatingPointRepresentation(false, digits("100"), -3, 3)), + arrayOf(-0.00999, FloatingPointRepresentation(false, digits("100"), -2, 3)), + arrayOf(-0.0999, FloatingPointRepresentation(false, digits("100"), -1, 3)), + arrayOf(-0.999, FloatingPointRepresentation(false, digits("100"), 0, 3)), + arrayOf(-9.99, FloatingPointRepresentation(false, digits("100"), 1, 3)), + arrayOf(-99.9, FloatingPointRepresentation(false, digits("100"), 2, 3)), + arrayOf(-999.0, FloatingPointRepresentation(false, digits("100"), 3, 3)), + + arrayOf(-0.001001, FloatingPointRepresentation(false, digits("100"), -3, 3)), + arrayOf(-0.01001, FloatingPointRepresentation(false, digits("100"), -2, 3)), + arrayOf(-0.1001, FloatingPointRepresentation(false, digits("100"), -1, 3)), + arrayOf(-1.001, FloatingPointRepresentation(false, digits("100"), 0, 3)), + arrayOf(-10.01, FloatingPointRepresentation(false, digits("100"), 1, 3)), + arrayOf(-100.1, FloatingPointRepresentation(false, digits("100"), 2, 3)), + arrayOf(-1001.0, FloatingPointRepresentation(false, digits("100"), 3, 3)), + + arrayOf(-0.0002999, FloatingPointRepresentation(false, digits("300"), -4, 3)), + arrayOf(-0.003999, FloatingPointRepresentation(false, digits("400"), -3, 3)), + arrayOf(-0.04999, FloatingPointRepresentation(false, digits("500"), -2, 3)), + arrayOf(-0.5999, FloatingPointRepresentation(false, digits("600"), -1, 3)), + arrayOf(-6.999, FloatingPointRepresentation(false, digits("700"), 0, 3)), + arrayOf(-79.99, FloatingPointRepresentation(false, digits("800"), 1, 3)), + arrayOf(-899.9, FloatingPointRepresentation(false, digits("900"), 2, 3)), + ) + } + + } + + @Test + fun run() { + // when + val actual = FloatingPointRepresentation.of(value, 3) + + // then + assertEquals(expected, actual, "value = $value") + } + +} From a685a953fa327b0650fc7e6998e4a6588b0baf9f Mon Sep 17 00:00:00 2001 From: Peva Blanchard Date: Sun, 23 Jul 2023 11:27:09 +0200 Subject: [PATCH 7/7] remove redundant class --- .../ui/toolwindow/DisplayedNumber.kt | 54 ------------------- .../toolwindow/FloatingPointRepresentation.kt | 39 ++++++++++++++ .../ui/toolwindow/InventoryTableModel.kt | 5 +- .../ui/toolwindow/DisplayedNumberTest.kt | 2 +- 4 files changed, 42 insertions(+), 58 deletions(-) delete mode 100644 src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt diff --git a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt deleted file mode 100644 index 686023beb..000000000 --- a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt +++ /dev/null @@ -1,54 +0,0 @@ -package ch.kleis.lcaplugin.ui.toolwindow - -import arrow.core.flatten -import arrow.core.replicate -import kotlin.math.* - -class DisplayedNumber( - value: Double, - nbSignificantDigits: Int = 3 -) { - private val repr = FloatingPointRepresentation.of(value, nbSignificantDigits) - - override fun toString(): String { - val isPositive = repr.isPositive - val digits = repr.digits - val nbSignificantDigits = repr.nbSignificantDigits - return when (val positionalExponent = repr.positionalExponent) { - in -2..-1 -> { - val hd = listOf(0).replicate(-positionalExponent - 1).flatten() - .joinToString("") - .let { "0.$it" } - val tl = digits.take(nbSignificantDigits - positionalExponent + 1) - .dropLastWhile { it == 0 } - .joinToString("") - val sign = if (isPositive) "" else "-" - "$sign$hd$tl" - } - in 0..2 -> { - val midpoint = min(positionalExponent + 1, nbSignificantDigits) - val hd = digits.subList(0, midpoint) - .joinToString("") - val tl = digits.subList(midpoint, nbSignificantDigits) - .dropLastWhile { it == 0 } - .joinToString("") - .let { if (it.isEmpty()) "" else ".$it" } - val sign = if (isPositive) "" else "-" - "$sign$hd$tl" - } - else -> { - val hd = digits.subList(0, 1) - .joinToString("") - val tl = digits.subList(1, nbSignificantDigits) - .dropLastWhile { it == 0 } - .joinToString("") - .let { if (it.isEmpty()) "" else ".$it" } - val sign = if (isPositive) "" else "-" - val e = "E$positionalExponent" - "$sign$hd$tl$e" - } - } - } -} - - diff --git a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentation.kt b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentation.kt index c199ff95f..2016f9730 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentation.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/FloatingPointRepresentation.kt @@ -58,4 +58,43 @@ data class FloatingPointRepresentation( return FloatingPointRepresentation(isPositive, digits, positionalExponent, nbSignificantDigits) } } + + override fun toString(): String { + return when (positionalExponent) { + in -2..-1 -> { + val hd = listOf(0).replicate(-positionalExponent - 1).flatten() + .joinToString("") + .let { "0.$it" } + val tl = digits.take(nbSignificantDigits - positionalExponent + 1) + .dropLastWhile { it == 0 } + .joinToString("") + val sign = if (isPositive) "" else "-" + "$sign$hd$tl" + } + + in 0..2 -> { + val midpoint = min(positionalExponent + 1, nbSignificantDigits) + val hd = digits.subList(0, midpoint) + .joinToString("") + val tl = digits.subList(midpoint, nbSignificantDigits) + .dropLastWhile { it == 0 } + .joinToString("") + .let { if (it.isEmpty()) "" else ".$it" } + val sign = if (isPositive) "" else "-" + "$sign$hd$tl" + } + + else -> { + val hd = digits.subList(0, 1) + .joinToString("") + val tl = digits.subList(1, nbSignificantDigits) + .dropLastWhile { it == 0 } + .joinToString("") + .let { if (it.isEmpty()) "" else ".$it" } + val sign = if (isPositive) "" else "-" + val e = "E$positionalExponent" + "$sign$hd$tl$e" + } + } + } } diff --git a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/InventoryTableModel.kt b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/InventoryTableModel.kt index 8417742fb..28ffcfe75 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/InventoryTableModel.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/InventoryTableModel.kt @@ -2,7 +2,6 @@ package ch.kleis.lcaplugin.ui.toolwindow import ch.kleis.lcaplugin.core.assessment.Inventory import ch.kleis.lcaplugin.core.lang.value.MatrixColumnIndex -import ch.kleis.lcaplugin.core.matrix.ImpactFactorMatrix import javax.swing.event.TableModelListener import javax.swing.table.TableModel @@ -59,7 +58,7 @@ class InventoryTableModel( val quantity = inventory.supply.quantityOf(outputProduct) if (columnIndex == 1) { - return DisplayedNumber(quantity.amount).toString() + return FloatingPointRepresentation.of(quantity.amount).toString() } if (columnIndex == 2) { return "${quantity.unit.symbol}" @@ -67,7 +66,7 @@ class InventoryTableModel( val inputProduct = sortedControllablePorts[columnIndex - 3] val ratio = inventory.impactFactors.valueRatio(outputProduct, inputProduct).amount - return DisplayedNumber(quantity.amount * ratio).toString() + return FloatingPointRepresentation.of(quantity.amount * ratio).toString() } override fun setValueAt(aValue: Any?, rowIndex: Int, columnIndex: Int) { 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 f72e82d65..30fed0e48 100644 --- a/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt +++ b/src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt @@ -60,7 +60,7 @@ class DisplayedNumberTest( @Test fun run() { // when - val actual = DisplayedNumber(value).toString() + val actual = FloatingPointRepresentation.of(value).toString() // then assertEquals(expected, actual)