[swift] Apple의 Swift 언어에서 난수를 어떻게 생성합니까?

Swift 책이 난수 생성기의 구현을 제공한다는 것을 알고 있습니다. 이 구현을 자신의 프로그램에 복사하여 붙여 넣는 것이 가장 좋은 방법입니까? 아니면 지금 사용할 수있는 라이브러리가 있습니까?



답변

스위프트 4.2 이상

Xcode 10과 함께 제공되는 Swift 4.2에는 다양한 데이터 유형에 사용하기 쉬운 새로운 임의 기능이 도입되었습니다. random()숫자 유형 에서 메소드를 호출 할 수 있습니다 .

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


답변

arc4random_uniform(n)0과 n-1 사이의 임의의 정수에 사용하십시오 .

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

결과를 Int로 캐스팅하면 var를 명시 적으로 입력 할 필요가 없습니다 UInt32(Swifty가 아닌 것처럼 보입니다).


답변

편집 : Swift 3.0 업데이트

arc4randomSwift에서는 잘 작동하지만 기본 기능은 32 비트 정수 유형 ( IntiPhone 5S 및 최신 Mac에서는 64 비트)으로 제한됩니다. 다음은 정수 리터럴로 표현할 수있는 임의의 숫자 유형에 대한 일반 함수입니다.

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

이 새로운 일반 함수를 사용하여 확장 UInt64하고 경계 인수를 추가하고 모듈러스 바이어스를 완화 할 수 있습니다 . (이것은 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
    }
}

이를 통해 우리는 Int64오버플로를 처리하면서 동일한 인수로 확장 할 수 있습니다 .

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
        }
    }
}

가족을 완성하려면 …

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
        }
    }
}

결국, 우리는 마침내 다음과 같이 할 수 있습니다 :

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


답변

스위프트 4.2 편집

가져온 C 함수 arc4random_uniform ()을 사용하는 대신 Swift 4.2부터 Swift 고유의 고유 함수를 사용할 수 있습니다.

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

random(in:)다른 기본 값에 대한 임의의 값을 얻는 데 사용할 수도 있습니다 . Int, Double, Float 및 Bool과 같은

스위프트 버전 <4.2

이 방법은 Int주어진 최소값과 최대 값 사이의 임의의 값 을 생성합니다

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


답변

나는이 코드를 사용했다 :

var k: Int = random() % 10;


답변

iOS 9부터 새로운 GameplayKit 클래스를 사용하여 다양한 방법으로 난수를 생성 할 수 있습니다.

선택할 수있는 네 가지 소스 유형이 있습니다 : 일반 무작위 소스 (이름이없는, 시스템의 기능을 선택하는 시스템까지), 선형 일치 성, ARC4 및 Mersenne Twister. 이들은 임의의 정수, 부동 소수점 및 부울을 생성 할 수 있습니다.

가장 간단한 수준에서 다음과 같이 시스템의 내장 임의 소스에서 난수를 생성 할 수 있습니다.

GKRandomSource.sharedRandom().nextInt()

이는 -2,147,483,648과 2,147,483,647 사이의 숫자를 생성합니다. 0과 상한 (제외) 사이의 숫자를 원하면 다음을 사용하십시오.

GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

GameplayKit에는 주사위와 함께 사용할 수있는 편리한 생성자가 있습니다. 예를 들어 다음과 같이 6 면체 주사위를 굴릴 수 있습니다.

let d6 = GKRandomDistribution.d6()
d6.nextInt()

또한 GKShuffledDistribution과 같은 것을 사용하여 무작위 분포를 형성 할 수 있습니다. 좀 더 설명이 필요하지만 관심이 있다면 GameplayKit 난수에 대한 튜토리얼을 읽을 .


답변

C에서와 동일한 방식으로 수행 할 수 있습니다.

let randomNumber = arc4random()

randomNumber유형 UInt32(32 비트 부호없는 정수) 인 것으로 추론됩니다.