Skip to content

Commit

Permalink
hopefully it works now
Browse files Browse the repository at this point in the history
  • Loading branch information
Peva Blanchard committed Jul 22, 2023
1 parent b78225d commit 949d750
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 51 deletions.
83 changes: 42 additions & 41 deletions src/main/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumber.kt
Original file line number Diff line number Diff line change
@@ -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.*
Expand All @@ -15,21 +16,24 @@ class DisplayedNumber(
init {
fun prepareNonZero(v: Double): Pair<Int, List<Int>> {
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<Int>()
var u = floor(w * (10.0.pow(shift))).toInt()
while (u > 0) {
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
Expand All @@ -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)
Expand All @@ -50,7 +54,7 @@ class DisplayedNumber(
}
}

fun getExponent(): Int {
fun getPositionalExponent(): Int {
return positionalExponent
}

Expand All @@ -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"
}
}
}
}

Expand Down
134 changes: 124 additions & 10 deletions src/test/kotlin/ch/kleis/lcaplugin/ui/toolwindow/DisplayedNumberTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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()
Expand Down

0 comments on commit 949d750

Please sign in to comment.