Fix Random.nextInt with bound that returned negative values

This commit is contained in:
Pavel Punegov
2018-07-10 19:45:15 +03:00
committed by Pavel Punegov
parent faee954d1a
commit 5879784536
4 changed files with 32 additions and 9 deletions
+6 -1
View File
@@ -499,8 +499,13 @@ task runtime_random(type: RunKonanTest) {
source = "runtime/basic/random.kt"
}
task runtime_random_bound(type: RunKonanTest) {
disabled = (project.testTarget == 'wasm32') // Uses exceptions.
source = "runtime/basic/random_bound.kt"
}
task runtime_worker_random(type: RunKonanTest) {
disabled = (project.testTarget == 'wasm32')
disabled = (project.testTarget == 'wasm32') // Uses workers.
source = "runtime/basic/worker_random.kt"
}
+13 -4
View File
@@ -52,11 +52,20 @@ fun testDiffInt() = testDifference { Random.nextInt() }
fun testDiffLong() = testDifference { Random.nextLong() }
@Test
fun testBoundInt() {
testReproducibility(1000L, { Random.nextInt(1000) })
fun testNextInt() {
testReproducibility(getTimeMillis(), { Random.nextInt(1000) })
testReproducibility(1000L, { Random.nextInt(1024) })
}
// test bounds
val bound = 5000
@Test
fun testBoundsNextInt() {
boundTest(5000)
boundTest(32)
boundTest(2)
boundTest(Int.MAX_VALUE)
}
private fun boundTest(bound: Int) {
val a = Array<Int>(100, { Random.nextInt(bound) })
a.forEach {
assertTrue(it >= 0, "Should be: $it >= 0")
@@ -0,0 +1,11 @@
package runtime.basic.random_bound
import kotlin.random.*
import kotlin.test.*
@Test
fun testBoundsNextInt() {
assertFailsWith<IllegalArgumentException>("Should fail on bound 0", { Random.nextInt(0) })
assertFailsWith<IllegalArgumentException>("Should fail on bound -100", { Random.nextInt(-100) })
assertFailsWith<IllegalArgumentException>("Should fail on bound ${Int.MIN_VALUE}", { Random.nextInt(Int.MIN_VALUE) })
}
@@ -15,9 +15,7 @@
*/
package kotlin.random
import konan.internal.*
import konan.worker.AtomicLong
import kotlin.random.Random.Companion.MULTIPLIER
import kotlin.system.getTimeNanos
abstract class Random {
@@ -61,12 +59,12 @@ abstract class Random {
if (bound <= 0) throw IllegalArgumentException("Incorrect bound: $bound")
if (bound and (bound - 1) == 0) {
return ((bound * nextInt().toLong()) shr 31).toInt();
return ((bound * (nextInt() ushr 1).toLong()) ushr 31).toInt();
}
var m: Int
do {
var r = nextInt()
var r = nextInt() ushr 1
m = r % bound
} while (r - m + (bound - 1) < 0)
return m