diff --git a/libraries/stdlib/samples/test/samples/random/randoms.kt b/libraries/stdlib/samples/test/samples/random/randoms.kt index 9d7b4e243ae..5bb24b70ec1 100644 --- a/libraries/stdlib/samples/test/samples/random/randoms.kt +++ b/libraries/stdlib/samples/test/samples/random/randoms.kt @@ -6,6 +6,7 @@ package samples.random import samples.* +import kotlin.math.sin import kotlin.random.Random import kotlin.test.assertTrue @@ -38,4 +39,105 @@ class Randoms { // random with another seed produce another sequence assertPrints(randomValues3, "[14, 48, 57, 67, 82, 7, 61, 27, 14, 59]") } -} \ No newline at end of file + + @Sample + fun nextBits() { + // always generates a 0 + println(Random.nextBits(0)) + // randomly generates a 0 or 1 + println(Random.nextBits(1)) + // generates a random non-negative Int value less than 256 + println(Random.nextBits(8)) + // generates a random Int value, may generate a negative value as well + println(Random.nextBits(32)) + } + + @Sample + fun nextBoolean() { + val presents = listOf("Candy", "Balloon", "Ball") + // a random partition, the result may be different every time + val (alicePresents, bobPresents) = presents.partition { Random.nextBoolean() } + + println("Alice receives $alicePresents") + println("Bob receives $bobPresents") + } + + @Sample + fun nextBytes() { + val bytes = ByteArray(4) + assertPrints(bytes.contentToString(), "[0, 0, 0, 0]") + + Random.nextBytes(bytes, 1, 3) + // second and third bytes are generated, rest unchanged + println(bytes.contentToString()) + + Random.nextBytes(bytes) + // all bytes are newly generated + println(bytes.contentToString()) + + val newBytes = Random.nextBytes(5) + // a new byte array filled with random values + println(newBytes.contentToString()) + } + + @Sample + fun nextDouble() { + if (Random.nextDouble() <= 0.3) { + println("There was 30% possibility of rainy weather today and it is raining.") + } else { + println("There was 70% possibility of sunny weather today and the sun is shining.") + } + } + + @Sample + fun nextDoubleFromUntil() { + val firstAngle = Random.nextDouble(until = Math.PI / 6); + assertTrue(sin(firstAngle) < 0.5) + + val secondAngle = Random.nextDouble(from = Math.PI / 6, until = Math.PI / 2) + val sinValue = sin(secondAngle) + assertTrue(sinValue >= 0.5 && sinValue < 1.0) + } + + @Sample + fun nextFloat() { + if (Random.nextFloat() <= 0.3) { + println("There was 30% possibility of rainy weather today and it is raining.") + } else { + println("There was 70% possibility of sunny weather today and the sun is shining.") + } + } + + @Sample + fun nextInt() { + val randomInts = List(5) { Random.nextInt() } + println(randomInts) + val sortedRandomInts = randomInts.sorted() + println(sortedRandomInts) + } + + @Sample + fun nextIntFromUntil() { + val menu = listOf("Omelette", "Porridge", "Cereal", "Chicken", "Pizza", "Pasta") + val forBreakfast = Random.nextInt(until = 3).let { menu[it] } + val forLunch = Random.nextInt(from = 3, until = 6).let { menu[it] } + // new meals every time + println("Today I want $forBreakfast for breakfast, and $forLunch for lunch.") + } + + @Sample + fun nextLong() { + val randomLongs = List(5) { Random.nextLong() } + println(randomLongs) + val sortedRandomLongs = randomLongs.sorted() + println(sortedRandomLongs) + } + + @Sample + fun nextLongFromUntil() { + val fileSize = Random.nextLong(until = 1_099_511_627_776) + println("A file of $fileSize bytes fits on a 1TB storage.") + val long = Random.nextLong(Int.MAX_VALUE + 1L, Long.MAX_VALUE) + println("Number $long doesn't fit in an Int.") + } +} diff --git a/libraries/stdlib/src/kotlin/random/Random.kt b/libraries/stdlib/src/kotlin/random/Random.kt index 823c69a8133..2532e2fd8f4 100644 --- a/libraries/stdlib/src/kotlin/random/Random.kt +++ b/libraries/stdlib/src/kotlin/random/Random.kt @@ -25,6 +25,8 @@ public abstract class Random { * Generates an `Int` whose lower [bitCount] bits are filled with random values and the remaining upper bits are zero. * * @param bitCount number of bits to generate, must be in range 0..32, otherwise the behavior is unspecified. + * + * @sample samples.random.Randoms.nextBits */ public abstract fun nextBits(bitCount: Int): Int @@ -32,6 +34,8 @@ public abstract class Random { * Gets the next random `Int` from the random number generator. * * Generates an `Int` random value uniformly distributed between `Int.MIN_VALUE` and `Int.MAX_VALUE` (inclusive). + * + * @sample samples.random.Randoms.nextInt */ public open fun nextInt(): Int = nextBits(32) @@ -43,6 +47,8 @@ public abstract class Random { * @param until must be positive. * * @throws IllegalArgumentException if [until] is negative or zero. + * + * @sample samples.random.Randoms.nextIntFromUntil */ public open fun nextInt(until: Int): Int = nextInt(0, until) @@ -52,6 +58,8 @@ public abstract class Random { * Generates an `Int` random value uniformly distributed between the specified [from] (inclusive) and [until] (exclusive) bounds. * * @throws IllegalArgumentException if [from] is greater than or equal to [until]. + * + * @sample samples.random.Randoms.nextIntFromUntil */ public open fun nextInt(from: Int, until: Int): Int { checkRangeBounds(from, until) @@ -81,6 +89,8 @@ public abstract class Random { * Gets the next random `Long` from the random number generator. * * Generates a `Long` random value uniformly distributed between `Long.MIN_VALUE` and `Long.MAX_VALUE` (inclusive). + * + * @sample samples.random.Randoms.nextLong */ public open fun nextLong(): Long = nextInt().toLong().shl(32) + nextInt() @@ -92,6 +102,8 @@ public abstract class Random { * @param until must be positive. * * @throws IllegalArgumentException if [until] is negative or zero. + * + * @sample samples.random.Randoms.nextLongFromUntil */ public open fun nextLong(until: Long): Long = nextLong(0, until) @@ -101,6 +113,8 @@ public abstract class Random { * Generates a `Long` random value uniformly distributed between the specified [from] (inclusive) and [until] (exclusive) bounds. * * @throws IllegalArgumentException if [from] is greater than or equal to [until]. + * + * @sample samples.random.Randoms.nextLongFromUntil */ public open fun nextLong(from: Long, until: Long): Long { checkRangeBounds(from, until) @@ -143,11 +157,15 @@ public abstract class Random { /** * Gets the next random [Boolean] value. + * + * @sample samples.random.Randoms.nextBoolean */ public open fun nextBoolean(): Boolean = nextBits(1) != 0 /** * Gets the next random [Double] value uniformly distributed between 0 (inclusive) and 1 (exclusive). + * + * @sample samples.random.Randoms.nextDouble */ public open fun nextDouble(): Double = doubleFromParts(nextBits(26), nextBits(27)) @@ -157,6 +175,8 @@ public abstract class Random { * Generates a `Double` random value uniformly distributed between 0 (inclusive) and [until] (exclusive). * * @throws IllegalArgumentException if [until] is negative or zero. + * + * @sample samples.random.Randoms.nextDoubleFromUntil */ public open fun nextDouble(until: Double): Double = nextDouble(0.0, until) @@ -168,6 +188,8 @@ public abstract class Random { * [from] and [until] must be finite otherwise the behavior is unspecified. * * @throws IllegalArgumentException if [from] is greater than or equal to [until]. + * + * @sample samples.random.Randoms.nextDoubleFromUntil */ public open fun nextDouble(from: Double, until: Double): Double { checkRangeBounds(from, until) @@ -183,6 +205,8 @@ public abstract class Random { /** * Gets the next random [Float] value uniformly distributed between 0 (inclusive) and 1 (exclusive). + * + * @sample samples.random.Randoms.nextFloat */ public open fun nextFloat(): Float = nextBits(24) / (1 shl 24).toFloat() @@ -191,6 +215,8 @@ public abstract class Random { * with random bytes. * * @return [array] with the subrange filled with random bytes. + * + * @sample samples.random.Randoms.nextBytes */ public open fun nextBytes(array: ByteArray, fromIndex: Int = 0, toIndex: Int = array.size): ByteArray { require(fromIndex in 0..array.size && toIndex in 0..array.size) { "fromIndex ($fromIndex) or toIndex ($toIndex) are out of range: 0..${array.size}." } @@ -221,11 +247,15 @@ public abstract class Random { * Fills the specified byte [array] with random bytes and returns it. * * @return [array] filled with random bytes. + * + * @sample samples.random.Randoms.nextBytes */ public open fun nextBytes(array: ByteArray): ByteArray = nextBytes(array, 0, array.size) /** * Creates a byte array of the specified [size], filled with random bytes. + * + * @sample samples.random.Randoms.nextBytes */ public open fun nextBytes(size: Int): ByteArray = nextBytes(ByteArray(size))