Generazione di numeri casuali con Swift

Ho bisogno di generare un numero casuale.

Sembra che la funzione arc4random non esista più così come la funzione arc4random_uniform .

Le opzioni disponibili sono arc4random_stir() , arc4random_buf(UnsafeMutablePointer, Int) e arc4random_addrandom(UnsafeMutablePointer, Int32) .

Non riesco a trovare alcun documento sulle funzioni e nessun commento nei file di intestazione fornisce suggerimenti.

===== 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 4.1 / Xcode 9 =====

arc4random() restituisce un numero casuale compreso tra 0 e 4 294 967 295

drand48() restituisce un numero casuale compreso tra 0.0 e 1.0

arc4random_uniform(N) restituisce un numero casuale compreso tra 0 e N - 1

Esempi:

 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 () è raccomandato su costruzioni come arc4random() % upper_bound in quanto evita "modulo bias" quando il limite superiore non è una potenza di due.

Potresti provare anche tu:

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

Ho dovuto aggiungere “UInt32” per farlo funzionare.

Basta chiamare questa funzione e fornire il numero minimo e massimo di numeri e otterrai un numero casuale.

eglike like randomNumber (MIN: 0, MAX: 10) e otterrai un numero compreso tra 0 e 9 .

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

Nota: – Otterrai sempre un numero intero in uscita.

Dopo alcune indagini ho scritto questo:

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

Ora puoi semplicemente eseguire Math.randomFraction() per ottenere numeri casuali [0..1 [senza dover ricordare prima il seeding. Spero che questo aiuti qualcuno: o)

Un’altra opzione è usare l’algoritmo 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 } 

Questo algoritmo ha un periodo di 2 ^ 128 – 1 e supera tutti i test della suite di test BigCrush . Si noti che mentre si tratta di un generatore di numeri pseudo-casuali di alta qualità con un lungo periodo, non si tratta di un generatore di numeri casuali crittograficamente sicuro .

Puoi seminarlo dall’ora corrente o da qualsiasi altra fonte casuale di entropia. Ad esempio, se avessi una funzione chiamata urand64() che legge un UInt64 da /dev/urandom , potresti usarla in questo modo:

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

In Swift 3:

Genera un numero casuale compreso tra 0 e il limite

 let limit : UInt32 = 6 print("Random Number : \(arc4random_uniform(limit))") 

La mia implementazione come estensione Int. Genera numeri casuali nell’intervallo from..

 public extension Int { static func random(from: Int, to: Int) -> Int { guard to > from else { assertionFailure("Can not generate negative random numbers") return 0 } return Int(arc4random_uniform(UInt32(to - from)) + UInt32(from)) } } 

Aggiornamento con swift 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) 

puoi usare questo in una percentuale specifica:

 let die = [1, 2, 3, 4, 5, 6] let firstRoll = die[Int(arc4random_uniform(UInt32(die.count)))] let secondRoll = die[Int(arc4random_uniform(UInt32(die.count)))] 

Consente di codice con Swift per il numero casuale o stringa casuale 🙂

 let quotes: NSArray = ["R", "A", "N", "D", "O", "M"] let randomNumber = arc4random_uniform(UInt32(quotes.count)) let quoteString = quotes[Int(randomNumber)] print(quoteString) 

ti darà output in modo casuale.

Non dimenticare che alcuni numeri si ripeteranno! quindi devi fare qualcosa come ….

la mia totale domande era 47.

 func getRandomNumbers(totalQuestions:Int) -> NSMutableArray { var arrayOfRandomQuestions: [Int] = [] print("arraySizeRequired = 40") print("totalQuestions = \(totalQuestions)") //This will output a 40 random numbers between 0 and totalQuestions (47) while arrayOfRandomQuestions.count < 40 { let limit: UInt32 = UInt32(totalQuestions) let theRandomNumber = (Int(arc4random_uniform(limit))) if arrayOfRandomQuestions.contains(theRandomNumber) { print("ping") } else { //item not found arrayOfRandomQuestions.append(theRandomNumber) } } print("Random Number set = \(arrayOfRandomQuestions)") print("arrayOutputCount = \(arrayOfRandomQuestions.count)") return arrayOfRandomQuestions as! NSMutableArray } 

Ecco come ottengo un numero casuale tra 2 int!

 func randomNumber(MIN: Int, MAX: Int)-> Int{ var list : [Int] = [] for i in MIN...MAX { list.append(i) } return list[Int(arc4random_uniform(UInt32(list.count)))] } 

utilizzo:

 print("My Random Number is: \(randomNumber(MIN:-10,MAX:10))") 

Un’altra opzione è usare GKMersenneTwisterRandomSource da GameKit. I documenti dicono:

Una fonte pseudo-casuale deterministica che genera numeri casuali basati su un algoritmo di mersenne twister. Questa è una fonte casuale deterministica adatta a creare meccaniche di gioco affidabili. È leggermente più lento di una sorgente Arc4, ma più casuale, in quanto ha un periodo più lungo fino a ripetere le sequenze. Mentre deterministico, questa non è una fonte casuale crittografica. È comunque adatto per l’offuscamento dei dati di gioco.

 import GameKit let minValue = 0 let maxValue = 100 var randomDistribution: GKRandomDistribution? let randomSource = GKMersenneTwisterRandomSource() randomDistribution = GKRandomDistribution(randomSource: randomSource, lowestValue: minValue, highestValue: maxValue) let number = randomDistribution?.nextInt() ?? 0 print(number) 

Esempio tratto dal codice di esempio di Apple: https://github.com/carekit-apple/CareKit/blob/master/CareKitPrototypingTool/OCKPrototyper/CareKitPatient/RandomNumberGeneratorHelper.swift

guarda, ho avuto lo stesso problema ma inserisco la funzione come variabile globale

come

 var RNumber = Int(arc4random_uniform(9)+1) func GetCase(){ your code } 

ovviamente questo non è efficace, quindi semplicemente copio e incollo il codice nella funzione in modo che possa essere riusabile, quindi xcode mi suggerisce di impostare var come costante in modo che il mio codice fosse

 func GetCase() { let RNumber = Int(arc4random_uniform(9)+1) if categoria == 1 { } } 

beh questa è una parte del mio codice, quindi xcode mi dice qualcosa di immutabile e di inizializzazione, ma, comunque, costruisce l’app e quel consiglio semplicemente scompare

spero che sia d’aiuto