diff --git a/libraries/stdlib/src/generated/_Ranges.kt b/libraries/stdlib/src/generated/_Ranges.kt index 6141f8ffaa4..8dae5b853ad 100644 --- a/libraries/stdlib/src/generated/_Ranges.kt +++ b/libraries/stdlib/src/generated/_Ranges.kt @@ -871,8 +871,10 @@ public fun Double.coerceIn(minimumValue: Double, maximumValue: Double): Double { public fun > T.coerceIn(range: ClosedComparableRange): T { if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: $range.") return when { - !range.lessThanOrEquals(range.start, this) -> range.start - !range.lessThanOrEquals(this, range.endInclusive) -> range.endInclusive + // this < start equiv to this <= start && !(this >= start) + range.lessThanOrEquals(this, range.start) && !range.lessThanOrEquals(range.start, this) -> range.start + // this > end equiv to this >= end && !(this <= end) + range.lessThanOrEquals(range.endInclusive, this) && !range.lessThanOrEquals(this, range.endInclusive) -> range.endInclusive else -> this } } diff --git a/libraries/stdlib/test/ranges/CoercionTest.kt b/libraries/stdlib/test/ranges/CoercionTest.kt index e63026cfe82..0c2d43ff983 100644 --- a/libraries/stdlib/test/ranges/CoercionTest.kt +++ b/libraries/stdlib/test/ranges/CoercionTest.kt @@ -67,8 +67,11 @@ class CoercionTest { fun coercionsDouble() { expect(5.0) { 5.0.coerceAtLeast(1.0) } expect(5.0) { 1.0.coerceAtLeast(5.0) } + assertTrue { Double.NaN.coerceAtLeast(1.0).isNaN() } + expect(1.0) { 5.0.coerceAtMost(1.0) } expect(1.0) { 1.0.coerceAtMost(5.0) } + assertTrue { Double.NaN.coerceAtMost(5.0).isNaN() } for (value in (0..10).map { it.toDouble() }) { expect(value) { value.coerceIn(null, null) } @@ -84,8 +87,12 @@ class CoercionTest { assertFails { 1.0.coerceIn(1.0, 0.0) } assertFails { 1.0.coerceIn(1.0..0.0) } + assertTrue(0.0.equals(0.0.coerceIn(0.0, -0.0))) assertTrue((-0.0).equals((-0.0).coerceIn(0.0..-0.0))) + + assertTrue(Double.NaN.coerceIn(0.0, 1.0).isNaN()) + assertTrue(Double.NaN.coerceIn(0.0..1.0).isNaN()) } @Test diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Comparables.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Comparables.kt index a7a9beb92c2..aed098f8454 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Comparables.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Comparables.kt @@ -103,8 +103,10 @@ fun comparables(): List { """ if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: ${'$'}range.") return when { - !range.lessThanOrEquals(range.start, this) -> range.start - !range.lessThanOrEquals(this, range.endInclusive) -> range.endInclusive + // this < start equiv to this <= start && !(this >= start) + range.lessThanOrEquals(this, range.start) && !range.lessThanOrEquals(range.start, this) -> range.start + // this > end equiv to this >= end && !(this <= end) + range.lessThanOrEquals(range.endInclusive, this) && !range.lessThanOrEquals(this, range.endInclusive) -> range.endInclusive else -> this } """