diff --git a/libraries/stdlib/js/src/kotlin/random/PlatformRandom.kt b/libraries/stdlib/js/src/kotlin/random/PlatformRandom.kt index 341a8600806..536d9ff463c 100644 --- a/libraries/stdlib/js/src/kotlin/random/PlatformRandom.kt +++ b/libraries/stdlib/js/src/kotlin/random/PlatformRandom.kt @@ -5,6 +5,8 @@ package kotlin.random +import kotlin.math.pow + internal actual fun defaultPlatformRandom(): Random = Random(js("(Math.random() * Math.pow(2, 32)) | 0").unsafeCast()) @@ -18,4 +20,9 @@ internal actual fun fastLog2(value: Int): Int { log++ } return log -} \ No newline at end of file +} + +private val INV_2_26: Double = 2.0.pow(-26) +private val INV_2_53: Double = 2.0.pow(-53) +internal actual fun doubleFromParts(hi26: Int, low27: Int): Double = + hi26 * INV_2_26 + low27 * INV_2_53 \ No newline at end of file diff --git a/libraries/stdlib/jvm/src/kotlin/random/PlatformRandom.kt b/libraries/stdlib/jvm/src/kotlin/random/PlatformRandom.kt index 1985736ce06..31ea8222c5b 100644 --- a/libraries/stdlib/jvm/src/kotlin/random/PlatformRandom.kt +++ b/libraries/stdlib/jvm/src/kotlin/random/PlatformRandom.kt @@ -31,6 +31,9 @@ internal actual inline fun defaultPlatformRandom(): Random = internal actual fun fastLog2(value: Int): Int = 31 - Integer.numberOfLeadingZeros(value) +internal actual fun doubleFromParts(hi26: Int, low27: Int): Double = + (hi26.toLong().shl(27) + low27) / (1L shl 53).toDouble() + internal abstract class AbstractPlatformRandom : Random() { abstract val impl: java.util.Random diff --git a/libraries/stdlib/src/kotlin/random/Random.kt b/libraries/stdlib/src/kotlin/random/Random.kt index a4c323a721a..37dde95416b 100644 --- a/libraries/stdlib/src/kotlin/random/Random.kt +++ b/libraries/stdlib/src/kotlin/random/Random.kt @@ -179,7 +179,7 @@ public abstract class Random { /** * Gets the next random [Double] value uniformly distributed between 0 (inclusive) and 1 (exclusive). */ - public open fun nextDouble(): Double = (nextBits(26).toLong().shl(27) + nextBits(27)) / (1L shl 53).toDouble() + public open fun nextDouble(): Double = doubleFromParts(nextBits(26), nextBits(27)) /** * Gets the next random non-negative `Double` from the random number generator not greater than the specified [bound]. @@ -327,6 +327,7 @@ public fun Random(seed: Long): Random = XorWowRandom(seed.toInt(), seed.shr(32). internal expect fun defaultPlatformRandom(): Random internal expect fun fastLog2(value: Int): Int // 31 - Integer.numberOfLeadingZeros(value) +internal expect fun doubleFromParts(hi26: Int, low27: Int): Double /** Takes upper [bitCount] bits (0..32) from this number. */ internal fun Int.takeUpperBits(bitCount: Int): Int =