# How does one generate a random number in Apple’s Swift language?

## Question or problem with Swift language programming:

I realize the Swift book provided an implementation of a random number generator. Is the best practice to copy and paste this implementation in one’s own program? Or is there a library that does this that we can use now?

## How to solve the problem:

### Solution 1:

Swift 4.2+

Swift 4.2 shipped with Xcode 10 introduces new easy-to-use random functions for many data types.
You can call the random() method on numeric types.

let randomInt = Int.random(in: 0..<6)
let randomDouble = Double.random(in: 2.71828...3.14159)
let randomBool = Bool.random()

### Solution 2:

Use arc4random_uniform(n) for a random integer between 0 and n-1.

let diceRoll = Int(arc4random_uniform(6) + 1)

Cast the result to Int so you don't have to explicitly type your vars as UInt32 (which seems un-Swifty).

### Solution 3:

Edit: Updated for Swift 3.0

arc4random works well in Swift, but the base functions are limited to 32-bit integer types (Int is 64-bit on iPhone 5S and modern Macs). Here's a generic function for a random number of a type expressible by an integer literal:

public func arc4random(_ type: T.Type) -> T {
var r: T = 0
arc4random_buf(&r, MemoryLayout.size)
return r
}

We can use this new generic function to extend UInt64, adding boundary arguments and mitigating modulo bias. (This is lifted straight from arc4random.c)

public extension UInt64 {
public static func random(lower: UInt64 = min, upper: UInt64 = max) -> UInt64 {
var m: UInt64
let u = upper - lower
var r = arc4random(UInt64.self)

if u > UInt64(Int64.max) {
m = 1 + ~u
} else {
m = ((max - (u * 2)) + 1) % u
}

while r < m {
r = arc4random(UInt64.self)
}

return (r % u) + lower
}
}

With that we can extend Int64 for the same arguments, dealing with overflow:

public extension Int64 {
public static func random(lower: Int64 = min, upper: Int64 = max) -> Int64 {
let (s, overflow) = Int64.subtractWithOverflow(upper, lower)
let u = overflow ? UInt64.max - UInt64(~s) : UInt64(s)
let r = UInt64.random(upper: u)

if r > UInt64(Int64.max)  {
return Int64(r - (UInt64(~lower) + 1))
} else {
return Int64(r) + lower
}
}
}

To complete the family...

private let _wordSize = __WORDSIZE

public extension UInt32 {
public static func random(lower: UInt32 = min, upper: UInt32 = max) -> UInt32 {
return arc4random_uniform(upper - lower) + lower
}
}

public extension Int32 {
public static func random(lower: Int32 = min, upper: Int32 = max) -> Int32 {
let r = arc4random_uniform(UInt32(Int64(upper) - Int64(lower)))
return Int32(Int64(r) + Int64(lower))
}
}

public extension UInt {
public static func random(lower: UInt = min, upper: UInt = max) -> UInt {
switch (_wordSize) {
case 32: return UInt(UInt32.random(UInt32(lower), upper: UInt32(upper)))
case 64: return UInt(UInt64.random(UInt64(lower), upper: UInt64(upper)))
default: return lower
}
}
}

public extension Int {
public static func random(lower: Int = min, upper: Int = max) -> Int {
switch (_wordSize) {
case 32: return Int(Int32.random(Int32(lower), upper: Int32(upper)))
case 64: return Int(Int64.random(Int64(lower), upper: Int64(upper)))
default: return lower
}
}
}

After all that, we can finally do something like this:

let diceRoll = UInt64.random(lower: 1, upper: 7)

### Solution 4:

Edit for Swift 4.2

Starting in Swift 4.2, instead of using the imported C function arc4random_uniform(), you can now use Swiftâ€™s own native functions.

// Generates integers starting with 0 up to, and including, 10
Int.random(in: 0 ... 10)

You can use random(in:) to get random values for other primitive values as well; such as Int, Double, Float and even Bool.

Swift versions < 4.2

This method will generate a random Int value between the given minimum and maximum

func randomInt(min: Int, max: Int) -> Int {
return min + Int(arc4random_uniform(UInt32(max - min + 1)))
}

### Solution 5:

I used this code:

var k: Int = random() % 10;