[swift] Swift로 난수 생성

난수를 생성해야합니다.

arc4random기능 과 기능이 더 이상 존재하지 않는 것 arc4random_uniform같습니다.

내가 가진 옵션은 arc4random_stir(), arc4random_buf(UnsafeMutablePointer<Void>, Int)하고 arc4random_addrandom(UnsafeMutablePointer<UInt8>, Int32).

함수에 대한 문서를 찾을 수 없으며 헤더 파일의 주석이 힌트를 제공하지 않습니다.



답변

===== Swift 4.2 / Xcode 10 =====

let randomIntFrom0To10 = Int.random(in: 1..<10)
let randomFloat = Float.random(in: 0..<1)

// if you want to get a random element in an array
let greetings = ["hey", "hi", "hello", "hola"]
greetings.randomElement()

내부적으로 Swift는 arc4random_buf작업을 수행하는 데 사용 합니다.

===== 스위프트 4.1 / Xcode 9 =====

arc4random()0 에서 4 294 967 295 범위의 난수를 반환합니다.

drand48()0.0 에서 1.0 사이 의 난수를 반환합니다.

arc4random_uniform(N)0 에서 N-1 범위의 난수를 반환합니다.

예 :

arc4random() // => UInt32 = 2739058784
arc4random() // => UInt32 = 2672503239
arc4random() // => UInt32 = 3990537167
arc4random() // => UInt32 = 2516511476
arc4random() // => UInt32 = 3959558840

drand48() // => Double = 0.88642843322303122
drand48() // => Double = 0.015582849408328769
drand48() // => Double = 0.58409022031727176
drand48() // => Double = 0.15936862653180484
drand48() // => Double = 0.38371587480719427

arc4random_uniform(3) // => UInt32 = 0
arc4random_uniform(3) // => UInt32 = 1
arc4random_uniform(3) // => UInt32 = 0
arc4random_uniform(3) // => UInt32 = 1
arc4random_uniform(3) // => UInt32 = 2

arc4random_uniform ()arc4random() % upper_bound상한이 2의 거듭 제곱이 아닐 때 “모듈로 바이어스”를 피하기 때문에 같은 구조보다 권장 됩니다.


답변

시도해 볼 수도 있습니다.

let diceRoll = Int(arc4random_uniform(UInt32(6)))

작동하려면 “UInt32″를 추가해야했습니다.


답변

이 함수를 호출하고 최소 및 최대 범위를 제공하면 임의의 숫자를 얻을 수 있습니다.

예. randomNumber (MIN : 0, MAX : 10) 와 같이 0에서 9 사이의 숫자를 얻게됩니다 .

func randomNumber(MIN: Int, MAX: Int)-> Int{
    return Int(arc4random_uniform(UInt32(MAX-MIN)) + UInt32(MIN));
}

참고 :-항상 Integer 숫자가 출력됩니다.


답변

몇 가지 조사 후 나는 이것을 썼다.

import Foundation

struct Math {
   private static var seeded = false

   static func randomFractional() -> CGFloat {

      if !Math.seeded {
         let time = Int(NSDate().timeIntervalSinceReferenceDate)
         srand48(time)
         Math.seeded = true
      }

      return CGFloat(drand48())
   }
}

이제 Math.randomFraction()시드를 먼저 기억할 필요없이 난수 [0..1 []를 얻을 수 있습니다 . 이것이 누군가에게 도움이되기를 바랍니다 : o)


답변

신속한 4.2 업데이트 :

let randomInt = Int.random(in: 1..<5)
let randomFloat = Float.random(in: 1..<10)
let randomDouble = Double.random(in: 1...100)
let randomCGFloat = CGFloat.random(in: 1...1000)


답변

또 다른 옵션은 xorshift128plus 알고리즘 을 사용하는 것입니다 .

func xorshift128plus(seed0 : UInt64, _ seed1 : UInt64) -> () -> UInt64 {
    var state0 : UInt64 = seed0
    var state1 : UInt64 = seed1
    if state0 == 0 && state1 == 0 {
        state0 = 1 // both state variables cannot be 0
    }

    func rand() -> UInt64 {
        var s1 : UInt64 = state0
        let s0 : UInt64 = state1
        state0 = s0
        s1 ^= s1 << 23
        s1 ^= s1 >> 17
        s1 ^= s0
        s1 ^= s0 >> 26
        state1 = s1
        return UInt64.addWithOverflow(state0, state1).0
    }

    return rand
}

이 알고리즘의주기는 2 ^ 128-1 이며 BigCrush 테스트 스위트 의 모든 테스트를 통과합니다 . 이것은 장기간의 고품질 의사 난수 생성기 이지만 암호 학적으로 안전한 난수 생성기는 아닙니다 .

현재 시간이나 다른 임의의 엔트로피 소스에서 시드 할 수 있습니다. 예를 들어 from urand64()을 읽는 함수가 있다면 다음 과 같이 사용할 수 있습니다.UInt64/dev/urandom

let rand = xorshift128plus(urand64(), urand64())
for _ in 1...10 {
    print(rand())
}


답변

let MAX : UInt32 = 9
let MIN : UInt32 = 1
func randomNumber()
{
   var random_number = Int(arc4random_uniform(MAX) + MIN)
   print ("random = ", random_number);
}