Skip to content

Commit 774542d

Browse files
committed
Fix: Uint and ULong.fromDouble() operations did not round
1 parent 3e40be5 commit 774542d

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

kotlinx.interval.testcases/src/commonMain/kotlin/TypeOperationsTest.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,24 @@ abstract class TypeOperationsTest<T : Comparable<T>>(
8585
}
8686
}
8787

88+
@Test
89+
fun fromDouble_rounds_to_nearest_value()
90+
{
91+
// Rounding only needed for evenly-spaced types.
92+
val spacing = typeOperations.spacing
93+
if ( spacing == null ) return
94+
95+
val next = typeOperations.unsafeAdd( a, spacing )
96+
val aDouble = typeOperations.toDouble( a )
97+
val nextDouble = typeOperations.toDouble( next )
98+
val oneThird = (nextDouble - aDouble) / 3
99+
val closerToA = aDouble + oneThird
100+
val closerToNext = nextDouble - oneThird
101+
102+
assertEquals( a, typeOperations.fromDouble( closerToA ) )
103+
assertEquals( next, typeOperations.fromDouble( closerToNext ) )
104+
}
105+
88106
@Test
89107
fun fromDouble_overflows_past_max()
90108
{

kotlinx.interval/src/commonMain/kotlin/BasicTypeOperations.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,11 @@ internal object UIntOperations : TypeOperations<UInt>
160160
override fun unsafeAdd( a: UInt, b: UInt ): UInt = a + b
161161
override fun unsafeSubtract( a: UInt, b: UInt ): UInt = a - b
162162

163-
override fun fromDouble( double: Double ): UInt = double.toUInt()
163+
override fun fromDouble( double: Double ): UInt
164+
{
165+
val uInt = double.toUInt()
166+
return if ( double - uInt.toDouble() >= 0.5 ) uInt + 1.toUInt() else uInt
167+
}
164168
override fun toDouble( value: UInt ): Double = value.toDouble()
165169
}
166170

@@ -174,7 +178,11 @@ internal object ULongOperations : TypeOperations<ULong>
174178
override fun unsafeAdd( a: ULong, b: ULong ): ULong = a + b
175179
override fun unsafeSubtract( a: ULong, b: ULong ): ULong = a - b
176180

177-
override fun fromDouble( double: Double ): ULong = double.toULong()
181+
override fun fromDouble( double: Double ): ULong
182+
{
183+
val uLong = double.toULong()
184+
return if ( double - uLong.toDouble() >= 0.5 ) uLong + 1.toULong() else uLong
185+
}
178186
override fun toDouble( value: ULong ): Double = value.toDouble()
179187
}
180188

0 commit comments

Comments
 (0)