Duration: round Double value to Long ns instead of truncating it KT-47675

This commit is contained in:
Ilya Gorbunov
2021-06-29 03:42:35 +03:00
committed by Space
parent 42cd2e65e6
commit 255c4b405e
3 changed files with 9 additions and 8 deletions
+3 -2
View File
@@ -9,6 +9,7 @@ import kotlin.contracts.*
import kotlin.jvm.JvmInline import kotlin.jvm.JvmInline
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.math.roundToLong
import kotlin.math.sign import kotlin.math.sign
/** /**
@@ -816,11 +817,11 @@ public fun Long.toDuration(unit: DurationUnit): Duration {
public fun Double.toDuration(unit: DurationUnit): Duration { public fun Double.toDuration(unit: DurationUnit): Duration {
val valueInNs = convertDurationUnit(this, unit, DurationUnit.NANOSECONDS) val valueInNs = convertDurationUnit(this, unit, DurationUnit.NANOSECONDS)
require(!valueInNs.isNaN()) { "Duration value cannot be NaN." } require(!valueInNs.isNaN()) { "Duration value cannot be NaN." }
val nanos = valueInNs.toLong() val nanos = valueInNs.roundToLong()
return if (nanos in -MAX_NANOS..MAX_NANOS) { return if (nanos in -MAX_NANOS..MAX_NANOS) {
durationOfNanos(nanos) durationOfNanos(nanos)
} else { } else {
val millis = convertDurationUnit(this, unit, DurationUnit.MILLISECONDS).toLong() val millis = convertDurationUnit(this, unit, DurationUnit.MILLISECONDS).roundToLong()
durationOfMillisNormalized(millis) durationOfMillisNormalized(millis)
} }
} }
+4 -4
View File
@@ -466,10 +466,10 @@ class DurationTest {
assertEquals("PT0.001S", Duration.milliseconds(1).toIsoString()) assertEquals("PT0.001S", Duration.milliseconds(1).toIsoString())
assertEquals("PT0.000001S", Duration.microseconds(1).toIsoString()) assertEquals("PT0.000001S", Duration.microseconds(1).toIsoString())
assertEquals("PT0.000000001S", Duration.nanoseconds(1).toIsoString()) assertEquals("PT0.000000001S", Duration.nanoseconds(1).toIsoString())
assertEquals("PT0.000000001S", Duration.nanoseconds(0.9).toIsoString())
// rounded to zero // rounded to zero
assertEquals("PT0S", Duration.nanoseconds(0.1).toIsoString()) assertEquals("PT0S", Duration.nanoseconds(0.1).toIsoString())
assertEquals("PT0S", Duration.nanoseconds(0.9).toIsoString())
// several units combined // several units combined
assertEquals("PT24H1M", (Duration.days(1) + Duration.minutes(1)).toIsoString()) assertEquals("PT24H1M", (Duration.days(1) + Duration.minutes(1)).toIsoString())
@@ -558,7 +558,7 @@ class DurationTest {
test(Duration.minutes(17.5), "17m 30s") test(Duration.minutes(17.5), "17m 30s")
test(Duration.minutes(16.5), "16m 30s") test(Duration.minutes(16.5), "16m 30s")
test(Duration.seconds(1097.1), "18m 17.099999999s") // Double to Long ns truncation! test(Duration.seconds(1097.1), "18m 17.100s")
test(Duration.seconds(90.36), "1m 30.360s") test(Duration.seconds(90.36), "1m 30.360s")
test(Duration.seconds(50), "50s") test(Duration.seconds(50), "50s")
test(Duration.seconds(1.3), "1.300s") test(Duration.seconds(1.3), "1.300s")
@@ -574,9 +574,9 @@ class DurationTest {
test(Duration.microseconds(75.35), "0.000075350s") test(Duration.microseconds(75.35), "0.000075350s")
test(Duration.microseconds(7.25), "0.000007250s") test(Duration.microseconds(7.25), "0.000007250s")
test(Duration.microseconds(1.035), "0.000001035s") test(Duration.microseconds(1.035), "0.000001035s")
test(Duration.microseconds(1.005), "0.000001004s") // Double to Long ns truncation! test(Duration.microseconds(1.005), "0.000001005s")
test(Duration.nanoseconds(950.5), "0.000000950s") test(Duration.nanoseconds(950.5), "0.000000951s")
test(Duration.nanoseconds(85.23), "0.000000085s") test(Duration.nanoseconds(85.23), "0.000000085s")
test(Duration.nanoseconds(8.235), "0.000000008s") test(Duration.nanoseconds(8.235), "0.000000008s")
test(Duration.nanoseconds(1.3), "0.000000001s") test(Duration.nanoseconds(1.3), "0.000000001s")
@@ -51,12 +51,12 @@ class TestTimeSourceTest {
val mark = timeSource.markNow() val mark = timeSource.markNow()
repeat(10_000) { repeat(10_000) {
timeSource += Duration.nanoseconds(0.9) timeSource += Duration.nanoseconds(0.4)
assertEquals(Duration.ZERO, mark.elapsedNow()) assertEquals(Duration.ZERO, mark.elapsedNow())
} }
timeSource += Duration.nanoseconds(1.9) timeSource += Duration.nanoseconds(1.9)
assertEquals(Duration.nanoseconds(1), mark.elapsedNow()) assertEquals(Duration.nanoseconds(2), mark.elapsedNow())
} }
} }