@@ -2013,205 +2013,4 @@ extension BinaryFloatingPoint where Self.RawSignificand: FixedWidthInteger {
20132013 guard exact else { return nil }
20142014 self = value_
20152015 }
2016-
2017- /// Returns a random value within the specified range, using the given
2018- /// generator as a source for randomness.
2019- ///
2020- /// Use this method to generate a floating-point value within a specific
2021- /// range when you are using a custom random number generator. This example
2022- /// creates three new values in the range `10.0 ..< 20.0`.
2023- ///
2024- /// for _ in 1...3 {
2025- /// print(Double.random(in: 10.0 ..< 20.0, using: &myGenerator))
2026- /// }
2027- /// // Prints "18.1900709259179"
2028- /// // Prints "14.2286325689993"
2029- /// // Prints "13.1485686260762"
2030- ///
2031- /// The `random(in:using:)` static method chooses a random value from a
2032- /// continuous uniform distribution in `range`, and then converts that value
2033- /// to the nearest representable value in this type. Depending on the size
2034- /// and span of `range`, some concrete values may be represented more
2035- /// frequently than others.
2036- ///
2037- /// - Note: The algorithm used to create random values may change in a future
2038- /// version of Swift. If you're passing a generator that results in the
2039- /// same sequence of floating-point values each time you run your program,
2040- /// that sequence may change when your program is compiled using a
2041- /// different version of Swift.
2042- ///
2043- /// - Parameters:
2044- /// - range: The range in which to create a random value.
2045- /// `range` must be finite and non-empty.
2046- /// - generator: The random number generator to use when creating the
2047- /// new random value.
2048- /// - Returns: A random value within the bounds of `range`.
2049- @inlinable
2050- public static func random< T: RandomNumberGenerator > (
2051- in range: Range < Self > ,
2052- using generator: inout T
2053- ) -> Self {
2054- _precondition (
2055- !range. isEmpty,
2056- " Can't get random value with an empty range "
2057- )
2058- let delta = range. upperBound - range. lowerBound
2059- // TODO: this still isn't quite right, because the computation of delta
2060- // can overflow (e.g. if .upperBound = .maximumFiniteMagnitude and
2061- // .lowerBound = -.upperBound); this should be re-written with an
2062- // algorithm that handles that case correctly, but this precondition
2063- // is an acceptable short-term fix.
2064- _precondition (
2065- delta. isFinite,
2066- " There is no uniform distribution on an infinite range "
2067- )
2068- let rand : Self . RawSignificand
2069- if Self . RawSignificand. bitWidth == Self . significandBitCount + 1 {
2070- rand = generator. next ( )
2071- } else {
2072- let significandCount = Self . significandBitCount + 1
2073- let maxSignificand : Self . RawSignificand = 1 << significandCount
2074- // Rather than use .next(upperBound:), which has to work with arbitrary
2075- // upper bounds, and therefore does extra work to avoid bias, we can take
2076- // a shortcut because we know that maxSignificand is a power of two.
2077- rand = generator. next ( ) & ( maxSignificand - 1 )
2078- }
2079- let unitRandom = Self . init ( rand) * ( Self . ulpOfOne / 2 )
2080- let randFloat = delta * unitRandom + range. lowerBound
2081- if randFloat == range. upperBound {
2082- return Self . random ( in: range, using: & generator)
2083- }
2084- return randFloat
2085- }
2086-
2087- /// Returns a random value within the specified range.
2088- ///
2089- /// Use this method to generate a floating-point value within a specific
2090- /// range. This example creates three new values in the range
2091- /// `10.0 ..< 20.0`.
2092- ///
2093- /// for _ in 1...3 {
2094- /// print(Double.random(in: 10.0 ..< 20.0))
2095- /// }
2096- /// // Prints "18.1900709259179"
2097- /// // Prints "14.2286325689993"
2098- /// // Prints "13.1485686260762"
2099- ///
2100- /// The `random()` static method chooses a random value from a continuous
2101- /// uniform distribution in `range`, and then converts that value to the
2102- /// nearest representable value in this type. Depending on the size and span
2103- /// of `range`, some concrete values may be represented more frequently than
2104- /// others.
2105- ///
2106- /// This method is equivalent to calling `random(in:using:)`, passing in the
2107- /// system's default random generator.
2108- ///
2109- /// - Parameter range: The range in which to create a random value.
2110- /// `range` must be finite and non-empty.
2111- /// - Returns: A random value within the bounds of `range`.
2112- @inlinable
2113- public static func random( in range: Range < Self > ) -> Self {
2114- var g = SystemRandomNumberGenerator ( )
2115- return Self . random ( in: range, using: & g)
2116- }
2117-
2118- /// Returns a random value within the specified range, using the given
2119- /// generator as a source for randomness.
2120- ///
2121- /// Use this method to generate a floating-point value within a specific
2122- /// range when you are using a custom random number generator. This example
2123- /// creates three new values in the range `10.0 ... 20.0`.
2124- ///
2125- /// for _ in 1...3 {
2126- /// print(Double.random(in: 10.0 ... 20.0, using: &myGenerator))
2127- /// }
2128- /// // Prints "18.1900709259179"
2129- /// // Prints "14.2286325689993"
2130- /// // Prints "13.1485686260762"
2131- ///
2132- /// The `random(in:using:)` static method chooses a random value from a
2133- /// continuous uniform distribution in `range`, and then converts that value
2134- /// to the nearest representable value in this type. Depending on the size
2135- /// and span of `range`, some concrete values may be represented more
2136- /// frequently than others.
2137- ///
2138- /// - Note: The algorithm used to create random values may change in a future
2139- /// version of Swift. If you're passing a generator that results in the
2140- /// same sequence of floating-point values each time you run your program,
2141- /// that sequence may change when your program is compiled using a
2142- /// different version of Swift.
2143- ///
2144- /// - Parameters:
2145- /// - range: The range in which to create a random value. Must be finite.
2146- /// - generator: The random number generator to use when creating the
2147- /// new random value.
2148- /// - Returns: A random value within the bounds of `range`.
2149- @inlinable
2150- public static func random< T: RandomNumberGenerator > (
2151- in range: ClosedRange < Self > ,
2152- using generator: inout T
2153- ) -> Self {
2154- _precondition (
2155- !range. isEmpty,
2156- " Can't get random value with an empty range "
2157- )
2158- let delta = range. upperBound - range. lowerBound
2159- // TODO: this still isn't quite right, because the computation of delta
2160- // can overflow (e.g. if .upperBound = .maximumFiniteMagnitude and
2161- // .lowerBound = -.upperBound); this should be re-written with an
2162- // algorithm that handles that case correctly, but this precondition
2163- // is an acceptable short-term fix.
2164- _precondition (
2165- delta. isFinite,
2166- " There is no uniform distribution on an infinite range "
2167- )
2168- let rand : Self . RawSignificand
2169- if Self . RawSignificand. bitWidth == Self . significandBitCount + 1 {
2170- rand = generator. next ( )
2171- let tmp : UInt8 = generator. next ( ) & 1
2172- if rand == Self . RawSignificand. max && tmp == 1 {
2173- return range. upperBound
2174- }
2175- } else {
2176- let significandCount = Self . significandBitCount + 1
2177- let maxSignificand : Self . RawSignificand = 1 << significandCount
2178- rand = generator. next ( upperBound: maxSignificand + 1 )
2179- if rand == maxSignificand {
2180- return range. upperBound
2181- }
2182- }
2183- let unitRandom = Self . init ( rand) * ( Self . ulpOfOne / 2 )
2184- let randFloat = delta * unitRandom + range. lowerBound
2185- return randFloat
2186- }
2187-
2188- /// Returns a random value within the specified range.
2189- ///
2190- /// Use this method to generate a floating-point value within a specific
2191- /// range. This example creates three new values in the range
2192- /// `10.0 ... 20.0`.
2193- ///
2194- /// for _ in 1...3 {
2195- /// print(Double.random(in: 10.0 ... 20.0))
2196- /// }
2197- /// // Prints "18.1900709259179"
2198- /// // Prints "14.2286325689993"
2199- /// // Prints "13.1485686260762"
2200- ///
2201- /// The `random()` static method chooses a random value from a continuous
2202- /// uniform distribution in `range`, and then converts that value to the
2203- /// nearest representable value in this type. Depending on the size and span
2204- /// of `range`, some concrete values may be represented more frequently than
2205- /// others.
2206- ///
2207- /// This method is equivalent to calling `random(in:using:)`, passing in the
2208- /// system's default random generator.
2209- ///
2210- /// - Parameter range: The range in which to create a random value. Must be finite.
2211- /// - Returns: A random value within the bounds of `range`.
2212- @inlinable
2213- public static func random( in range: ClosedRange < Self > ) -> Self {
2214- var g = SystemRandomNumberGenerator ( )
2215- return Self . random ( in: range, using: & g)
2216- }
22172016}
0 commit comments