-
-
Save alemar11/ed18a9d94092d83cae2fd42fd5cc55ef to your computer and use it in GitHub Desktop.
Random numbers in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Darwin | |
extension Integer { | |
static func makeRandomValue() -> Self { | |
var result: Self = 0 | |
withUnsafeMutablePointer(&result) { resultPtr in | |
arc4random_buf(UnsafeMutablePointer(resultPtr), sizeof(Self.self)) | |
} | |
return result | |
} | |
} | |
// From SE-0104 (just the bits I need) | |
public protocol FixedWidthInteger : Integer { | |
static var max: Self { get } | |
static var min: Self { get } | |
} | |
extension UInt64: FixedWidthInteger {} | |
extension Int64: FixedWidthInteger {} | |
extension UInt32: FixedWidthInteger {} | |
extension Int32: FixedWidthInteger {} | |
extension UInt16: FixedWidthInteger {} | |
extension Int16: FixedWidthInteger {} | |
extension UInt8: FixedWidthInteger {} | |
extension Int8: FixedWidthInteger {} | |
extension UInt: FixedWidthInteger {} | |
extension Int: FixedWidthInteger {} | |
extension FixedWidthInteger where Stride: SignedInteger { // Feels strange that I need this where clause | |
static func makeRandomValue(in range: CountableClosedRange<Self>) -> Self { | |
let rangeSize = range.upperBound - range.lowerBound | |
var randomValue = makeRandomValue() | |
let (s, overflow) = subtractWithOverflow(range.upperBound, range.lowerBound) | |
let maxDivisible = overflow ? max - ~s : s | |
while randomValue < maxDivisible { | |
randomValue = makeRandomValue() | |
} | |
return (randomValue % rangeSize) + range.lowerBound | |
} | |
} | |
UInt64.makeRandomValue(in: 5...6) | |
Int64.makeRandomValue(in: -10...10) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment