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로 . 그러면 명시적으로 다음과 같이 여러분의 대표팀을 입력할 필요가 없습니다.UInt32('아예')
편집: Swift 3.0용으로 갱신
arc4randomSwift에서 Swift)으로 됩니다.Int5S, Mac, 64S).정수 리터럴로 표현할 수 있는 유형의 난수에 대한 일반적인 함수를 다음에 나타냅니다.
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
}
}
으로 with를통통리 with with를 연장할 수 .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)
Swift 4.2용 편집
Swift 4.2부터는 Import된 C 함수 arc4random_uniform() 대신 Swift 자체 네이티브 함수를 사용할 수 있게 되었습니다.
// Generates integers starting with 0 up to, and including, 10
Int.random(in: 0 ... 10)
하시면 됩니다.random(in:)Int, Double, Float, ol과 Bool 른른 른른 른 int int int int int int int int int int int int int int int 。
Swift 버전 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 등 4가지입니다.이것들은 랜덤 int, 플로트 및 bool을 생성할 수 있습니다.
가장 간단한 수준에서 다음과 같이 시스템에 내장된 랜덤 소스에서 랜덤 번호를 생성할 수 있습니다.
GKRandomSource.sharedRandom().nextInt()
그러면 -2,147,483,648에서 2,147,483,647 사이의 숫자가 생성됩니다.0에서 상한(전용) 사이의 숫자를 원하는 경우 다음을 사용합니다.
GKRandomSource.sharedRandom().nextIntWithUpperBound(6)
GameplayKit에는 주사위 조작을 위한 편리한 컨스트럭터가 내장되어 있습니다.예를 들어, 다음과 같이 6면 다이를 굴릴 수 있습니다.
let d6 = GKRandomDistribution.d6()
d6.nextInt()
또한 GKShuffled Distribution과 같은 것을 사용하여 랜덤 분포를 형성할 수 있습니다.좀 더 설명이 필요하지만, 만약 당신이 관심이 있다면 게임 플레이 키트의 랜덤 번호에 대한 나의 튜토리얼을 읽어보실 수 있습니다.
C에서와 같은 방법으로 실행할 수 있습니다.
let randomNumber = arc4random()
randomNumber으로 UInt32 정수)(32비트 부호 없는 정수
arc4random_uniform()
사용방법:
arc4random_uniform(someNumber: UInt32) -> UInt32
임의의 가 ''의 로 표시됩니다.0로로 합니다.someNumber - 1.
「」의 .UInt324, 4,294,967,295)입니다.2^32 - 1를 참조해 주세요.
예:
동전 던지기
let flip = arc4random_uniform(2) // 0 or 1주사위 굴리기
let roll = arc4random_uniform(6) + 1 // 1...610월의 랜덤 데이
let day = arc4random_uniform(31) + 1 // 1...311990년대 랜덤 연도
let year = 1990 + arc4random_uniform(10)
일반 양식:
let number = min + arc4random_uniform(max - min + 1)
서 ''는number,max , , , , 입니다.minUInt32.
그럼...
arc4param()
'아무렇게나 하다'를 수 있습니다.arc4random()에 의해, 「」가 됩니다).UInt32 ~ 0 ~2^32-1 사이.따라서 다음 중 임의의 숫자를 얻으려면0 ★★★★★★★★★★★★★★★★★」x-1x나머지를 가져가세요.즉, 나머지 연산자(%)를 사용합니다.
let number = arc4random() % 5 // 0...4
단, 이는 약간의 모듈로 바이어스(여기와 여기도 참조)를 발생시키기 때문에arc4random_uniform()를 권장합니다.
환 and and conver conver 변환Int
이런 요, 이렇게 돼요, 이렇게 돼요.Int ★★★★★★★★★★★★★★★★★」UInt32:
let number: Int = 10
let random = Int(arc4random_uniform(UInt32(number)))
하지만 문제는, 그 범위가-2,147,483,648...2,147,483,647 및 의 " " " " 입니다.-9,223,372,036,854,775,808...9,223,372,036,854,775,80764세을 「 」와 비교해 주세요.UInt32의 0...4,294,967,295 . 。UUInt32부호 없는 것을 의미합니다.
다음 오류를 고려하십시오.
UInt32(-1) // negative numbers cause integer overflow error
UInt32(4294967296) // numbers greater than 4,294,967,295 cause integer overflow error
입력 가 '어느 정도' 안에 .UInt32또한 이 범위를 벗어나는 출력도 필요하지 않습니다.
10(0-9) 사이의 난수 예제
import UIKit
let randomNumber = Int(arc4random_uniform(10))
매우 쉬운 코드 - 심플하고 짧습니다.
는 그냥 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.rand()을 참조하다 해서 수
let myVar: Int = Int(rand())
마음에 드는 C랜덤 함수를 사용하여 필요에 따라 Int로 변환할 수 있습니다.
@jstn의 답변은 좋지만 좀 장황하다.Swift는 프로토콜 지향 언어로 알려져 있기 때문에 프로토콜 확장을 위한 기본 구현을 추가함으로써 정수 패밀리의 모든 클래스에 대해 보일러 플레이트 코드를 구현할 필요 없이 동일한 결과를 얻을 수 있습니다.
public extension ExpressibleByIntegerLiteral {
public static func arc4random() -> Self {
var r: Self = 0
arc4random_buf(&r, MemoryLayout<Self>.size)
return r
}
}
이제 다음을 할 수 있습니다.
let i = Int.arc4random()
let j = UInt32.arc4random()
기타 정수 클래스는 모두 OK입니다.
갱신일 : 2022년6월 9일
스위프트 5.7
어레이가 있다고 가정합니다.
let numbers: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
iOS 및 MacOS에서는 Xcode 프레임워크에서 시스템 전체의 랜덤 소스를 사용할 수 있습니다.GameKit .GKRandomSource ('를 가진 .sharedRandom()다음 중 하나:
import GameKit
private func randomNumberGenerator() -> Int {
let rand = GKRandomSource.sharedRandom().nextInt(upperBound: numbers.count)
return numbers[rand]
}
randomNumberGenerator()
, ,을 사용할 수 있습니다.randomElement()'CHANGE: 'CHANGE: 'CHANGE: 'CHANGE: 'CHANGE:
let randomNumber = numbers.randomElement()!
print(randomNumber)
「」를 사용합니다.arc4random_uniform()가 반환하는 은, 주의해 UInt32discloss.discloss.
let generator = Int(arc4random_uniform(11))
print(generator)
물론 '아까', '아까', '아까', '아까'를 할 수 .makeIterator()컬렉션 요소 위에 반복기를 반환하는 메서드입니다.
let iterator: Int = (1...10).makeIterator().shuffled().first!
print(iterator)
에서는 지정된 내의 이 예에서는, 「알겠습니다」를 하고 있습니다.static func random(in range: ClosedRange<Int>) -> Int.
let randomizer = Int.random(in: 1...10)
print(randomizer)
생성기drand48()는 0.0 .0합니다.
import Foundation
let randomInt = Int(drand48() * 10)
Swift 4.2 에서는, 다음의 콜에 의해서 랜덤 번호를 생성할 수 있습니다.random()원하는 숫자 유형에 대한 메서드를 사용하여 원하는 범위를 제공합니다.를 들어, 이것은 한 1~합니다.
let randInt = Int.random(in: 1..<10)
다른 타입과 함께
let randFloat = Float.random(in: 1..<20)
let randDouble = Double.random(in: 1...30)
let randCGFloat = CGFloat.random(in: 1...40)
Swift 4.2 이후
새로운 API 세트가 있습니다.
let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
let randomDouble = Double.random(in: 1 ... 10)
이제 모든 숫자 유형은 다음과 같은 방법을 사용합니다.
range.이 범위 내에서 균등하게 분포된 숫자를 반환합니다.
TL;DR
음, "좋은" 옛 방식이 뭐가 문제죠?
Import된 C API를 사용해야 합니다(플랫폼마다 다릅니다).
게다가...
만약 내가 랜덤이 그렇게 랜덤이 아니라고 말한다면요?
「 」를 사용하고 arc4random() (나머지를 계산하기 위해) 같은arc4random() % aNumber, 그 결과는, 각 네트워크간에 균등하게 분포되어 있지 않습니다.0 ★★★★★★★★★★★★★★★★★」aNumber모듈로 편향이라는 문제가 있습니다.
모듈로 바이어스
는 이 함수의 를 생성하는데, 즉, 이 함수는 이 함수의 난수를 합니다.0 및 MAX(유형 등에 따라 다름)입니다.예를 들면, 예를 들면, 최대수는 다음과 같습니다.7, 「」의 번호에 이 있습니다.0 ..< 2 (또는 인터벌[0, 3)]를 선택합니다).
개별 번호의 확률은 다음과 같습니다.
- 0: 3/8 = 37.5%
- 1: 3/8 = 37.5%
- 2: 2/8 = 25%
즉, 2보다 0 또는 1이 될 가능성이 높습니다.물론, 이것은 지극히 심플하고, MAX의 수치가 훨씬 높기 때문에, 보다 「공정」하게 됩니다.
여기 그 일을 잘 하는 도서관이 있습니다. https://github.com/thellimist/SwiftRandom
public extension Int {
/// SwiftRandom extension
public static func random(lower: Int = 0, _ upper: Int = 100) -> Int {
return lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
}
}
public extension Double {
/// SwiftRandom extension
public static func random(lower: Double = 0, _ upper: Double = 100) -> Double {
return (Double(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
}
}
public extension Float {
/// SwiftRandom extension
public static func random(lower: Float = 0, _ upper: Float = 100) -> Float {
return (Float(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
}
}
public extension CGFloat {
/// SwiftRandom extension
public static func random(lower: CGFloat = 0, _ upper: CGFloat = 1) -> CGFloat {
return CGFloat(Float(arc4random()) / Float(UINT32_MAX)) * (upper - lower) + lower
}
}
let MAX : UInt32 = 9
let MIN : UInt32 = 1
func randomNumber()
{
var random_number = Int(arc4random_uniform(MAX) + MIN)
print ("random = ", random_number);
}
Swift 책에 있는 난수 발생기의 예는 Linear Congruence Generator(LCG; 선형 결합 발생기)이며, 이는 매우 제한적인 것이며, 랜덤성의 품질이 전혀 중요하지 않은 필수 예제를 제외하면 안 된다는 기존 답변을 추가하고 싶습니다.또한 LCG는 암호화 목적으로 사용해서는 안 됩니다.
arc4random()는 훨씬 우수하고 대부분의 용도로 사용할 수 있지만 암호화 용도로는 사용하지 마십시오.
되는 것을 를 합니다.SecCopyRandomBytes(). 생성기를패스워드,등를수암호화 목적(패스워드, 키, 솔트 생성 등)에 사용할 수 있습니다.그러면 사용을 검토해야 합니다.SecCopyRandomBytes()그게 꼭 필요한 건 아니더라도 말이야
스위프트 4.2
Foundation Clib 에 Bye byearc4random_uniform()
// 1
let digit = Int.random(in: 0..<10)
// 2
if let anotherDigit = (0..<10).randomElement() {
print(anotherDigit)
} else {
print("Empty range.")
}
// 3
let double = Double.random(in: 0..<1)
let float = Float.random(in: 0..<1)
let cgFloat = CGFloat.random(in: 0..<1)
let bool = Bool.random()
- random(in:)을 사용하여 범위에서 임의의 숫자를 생성합니다.
- randomElement()는 범위가 비어 있는 경우 0을 반환하므로 반환된 Int?는 let을 사용하여 래핑을 해제합니다.
- 랜덤(in:)을 사용하여 랜덤 Double, Float 또는 CGFloat을 생성하고 랜덤 부울을 반환하는 random()을 사용합니다.
var randomNumber = Int(arc4random_uniform(UInt32(5)))
여기서 5는 0부터4까지의 난수를 생성합니다.그에 따라 값을 설정할 수 있습니다.
Xcode의 일부 버전에서는 arc4Random_uniform()이 없을 경우(7.1에서는 실행되지만 자동으로 완료되지 않음)대신 이렇게 하시면 됩니다.
0 ~ 5의 난수를 생성합니다.첫번째
import GameplayKit
그리고나서
let diceRoll = GKRandomSource.sharedRandom().nextIntWithUpperBound(6)
다음 코드는 0에서 255 사이의 안전한 난수를 생성합니다.
extension UInt8 {
public static var random: UInt8 {
var number: UInt8 = 0
_ = SecRandomCopyBytes(kSecRandomDefault, 1, &number)
return number
}
}
이렇게 부르죠.
print(UInt8.random)
이치노
「 」 「 」 、 「 」 、 「 」 。
extension UInt16 {
public static var random: UInt16 {
let count = Int(UInt8.random % 2) + 1
var numbers = [UInt8](repeating: 0, count: 2)
_ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
return numbers.reversed().reduce(0) { $0 << 8 + UInt16($1) }
}
}
extension UInt32 {
public static var random: UInt32 {
let count = Int(UInt8.random % 4) + 1
var numbers = [UInt8](repeating: 0, count: 4)
_ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
return numbers.reversed().reduce(0) { $0 << 8 + UInt32($1) }
}
}
하여 몇 의 난수를 합니다.UInt8는 난수 작성에 사용됩니다.은 을 합니다.[UInt8]로로 합니다.UInt16 ★★★★★★★★★★★★★★★★★」UInt32.
마지막 두 개가 정말 랜덤으로 간주될지는 모르겠지만, 취향에 맞게 조정할 수 있습니다.
스위프트 4.2
Swift 4.2는 표준 라이브러리에 네이티브로 완전 기능을 갖춘 난수 API를 포함했습니다.(Swift Evolution 제안 SE-0202)
let intBetween0to9 = Int.random(in: 0...9)
let doubleBetween0to1 = Double.random(in: 0...1)
모든 번호 유형에는 정적 랜덤(in:)이 있습니다.이것에 의해, 범위를 취득해, 소정의 범위의 랜덤 번호를 반환합니다.
Xcode 14, 스위프트 5
public extension Array where Element == Int {
static func generateNonRepeatedRandom(size: Int) -> [Int] {
guard size > 0 else {
return [Int]()
}
return Array(0..<size).shuffled()
}
}
사용방법:
let array = Array.generateNonRepeatedRandom(size: 15)
print(array)
산출량
하시면 됩니다.GeneratorOf음음음같 뭇매하다
var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
_ -> Int? in
fibs.append(fibs.reduce(0, combine:+))
return fibs.removeAtIndex(0)
}
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
이 코드를 사용하여 난수를 생성합니다.
//
// FactModel.swift
// Collection
//
// Created by Ahmadreza Shamimi on 6/11/16.
// Copyright © 2016 Ahmadreza Shamimi. All rights reserved.
//
import GameKit
struct FactModel {
let fun = ["I love swift","My name is Ahmadreza","I love coding" ,"I love PHP","My name is ALireza","I love Coding too"]
func getRandomNumber() -> String {
let randomNumber = GKRandomSource.sharedRandom().nextIntWithUpperBound(fun.count)
return fun[randomNumber]
}
}
세부 사항
xCode 9.1, Swift 4
수학 지향 솔루션 (1)
import Foundation
class Random {
subscript<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
get {
return rand(min-1, max+1)
}
}
}
let rand = Random()
func rand<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
let _min = min + 1
let difference = max - _min
return T(arc4random_uniform(UInt32(difference))) + _min
}
솔루션 사용방법 (1)
let x = rand(-5, 5) // x = [-4, -3, -2, -1, 0, 1, 2, 3, 4]
let x = rand[0, 10] // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
프로그래머 지향 솔루션 (2)
여기에 수학 지향 솔루션 (1) 코드를 추가하는 것을 잊지 마십시오.
import Foundation
extension CountableRange where Bound : BinaryInteger {
var random: Bound {
return rand(lowerBound-1, upperBound)
}
}
extension CountableClosedRange where Bound : BinaryInteger {
var random: Bound {
return rand[lowerBound, upperBound]
}
}
솔루션 사용(2)
let x = (-8..<2).random // x = [-8, -7, -6, -5, -4, -3, -2, -1, 0, 1]
let x = (0..<10).random // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
let x = (-10 ... -2).random // x = [-10, -9, -8, -7, -6, -5, -4, -3, -2]
풀샘플
여기에 솔루션 (1) 및 솔루션 (2) 코드를 추가하는 것을 잊지 마십시오.
private func generateRandNums(closure:()->(Int)) {
var allNums = Set<Int>()
for _ in 0..<100 {
allNums.insert(closure())
}
print(allNums.sorted{ $0 < $1 })
}
generateRandNums {
(-8..<2).random
}
generateRandNums {
(0..<10).random
}
generateRandNums {
(-10 ... -2).random
}
generateRandNums {
rand(-5, 5)
}
generateRandNums {
rand[0, 10]
}
샘플 결과
언급URL : https://stackoverflow.com/questions/24007129/how-to-generate-a-random-number-in-swift
'programing' 카테고리의 다른 글
| git 오류: RPC 실패, 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054 (0) | 2023.04.22 |
|---|---|
| 디렉토리에서 일부 파일을 제외한 모든 파일 제거 (0) | 2023.04.22 |
| 도메인 객체, POCO 및 엔티티의 차이점은 무엇입니까? (0) | 2023.04.22 |
| Bash 인수에서 따옴표를 유지하는 방법 (0) | 2023.04.22 |
| Swift에서 사전에 요소를 추가하는 방법은 무엇입니까? (0) | 2023.04.22 |

