Générer des nombres aléatoires avec Swift

J'ai besoin de générer un nombre aléatoire.

Il semble que la fonction arc4random n'existe plus ainsi que la fonction arc4random_uniform.

Les options que j'ai sont arc4random_stir(), arc4random_buf(UnsafeMutablePointer<Void>, Int), et arc4random_addrandom(UnsafeMutablePointer<UInt8>, Int32).

Je ne trouve aucun document sur les fonctions et aucun commentaire dans les fichiers d'en-tête ne donne d'indices.

77
demandé sur Moritz 2015-09-13 20:11:05

15 réponses

===== 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() renvoie un nombre aléatoire dans l'intervalle de 0 pour 4 294 967 295

drand48() renvoie un nombre aléatoire dans l'intervalle de 0.0 pour 1.0

arc4random_uniform(N) renvoie un nombre aléatoire dans l'intervalle de 0 de N - 1

Exemples:

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 () {[8] } est recommandé sur des constructions comme arc4random() % upper_bound car il évite le "biais modulo" lorsque la limite supérieure n'est pas une puissance de deux.

203
répondu Arsen 2018-06-06 09:56:54

Vous pouvez aussi essayer:

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

J'ai dû ajouter "UInt32" pour le faire fonctionner.

20
répondu Fernando Cardenas 2016-01-18 14:50:48

Il suffit d'appeler cette fonction et de fournir une portée minimale et maximale du nombre et vous obtiendrez un nombre aléatoire.

Par exemple.comme randomNumber(MIN: 0, MAX: 10) et vous obtiendrez le nombre entre 0 à 9.

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

Note: - vous obtiendrez toujours un nombre entier.

6
répondu PRAVEEN 2018-03-06 05:25:24

Après une enquête, j'ai écrit ceci:

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

Maintenant, vous pouvez simplement faire Math.randomFraction() pour obtenir des nombres aléatoires [0..1 [sans avoir à se souvenir de l'ensemencement en premier. J'espère que cela aide quelqu'un: o)

5
répondu Melodius 2016-03-10 14:55:23

Une autre option consiste à utiliser l'algorithme 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
}

Cet algorithme a une période de 2^128-1 et passe tous les tests de la suite de testsBigCrush . Notez que s'il s'agit d'un générateur de nombres pseudo-aléatoires de haute qualité avec une longue période, ce n'est pas un générateur de nombres aléatoires cryptographiquement sécurisé.

Vous pouvez le semer à partir de l'heure actuelle ou de toute autre source aléatoire d'entropie. Par exemple, si vous avez eu une fonction appelé urand64() qui lit un UInt64 de /dev/urandom, Vous pouvez l'utiliser comme ceci:

let rand = xorshift128plus(urand64(), urand64())
for _ in 1...10 {
    print(rand())
}
1
répondu David Conrad 2016-05-18 21:32:15
let MAX : UInt32 = 9
let MIN : UInt32 = 1 
func randomNumber()
{
   var random_number = Int(arc4random_uniform(MAX) + MIN)
   print ("random = ", random_number);    
}
1
répondu Rajesh Sharma 2016-05-28 15:27:01

Dans Swift 3:

Il va générer un nombre aléatoire entre 0 pour limiter

let limit : UInt32 = 6
print("Random Number : \(arc4random_uniform(limit))")
1
répondu Mili Shah 2017-03-24 13:13:13

Mon implémentation en tant qu'extension Int. Va générer des nombres aléatoires dans la plage from..<to

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))
    }
}
1
répondu anatoliy_v 2017-06-05 14:39:00

Mise à Jour avec 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)
1
répondu Quentin N 2018-06-05 16:49:13

Vous pouvez l'utiliser dans le taux spécifique:

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)))]
0
répondu M.zar 2017-02-05 09:55:45

Permet de coder avec Swift pour le nombre aléatoire ou la chaîne aléatoire:)

let quotes: NSArray = ["R", "A", "N", "D", "O", "M"]

      let randomNumber = arc4random_uniform(UInt32(quotes.count))
      let quoteString = quotes[Int(randomNumber)]
      print(quoteString)

Il vous donnera la sortie au hasard.

0
répondu Azharhussain Shaikh 2017-05-31 12:31:39

N'oubliez pas que certains chiffres vont se répéter! donc, vous devez faire quelque chose comme....

Mon totalQuestions était 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

}
0
répondu user2986119 2017-07-07 15:37:52

C'est ainsi que j'obtiens un nombre aléatoire entre 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)))]
}

Utilisation:

print("My Random Number is: \(randomNumber(MIN:-10,MAX:10))")
0
répondu Ilan Sagital 2017-11-17 13:22:20

Une autre option consiste à utiliser GKMersenneTwisterRandomSource de GameKit. Les docs disent:

Une source pseudo-aléatoire déterministe qui génère des nombres aléatoires basé sur un algorithme de Mersenne twister. C'est un aléatoire déterministe source appropriée pour créer des mécanismes de jeu fiables. Il est légèrement plus lent qu'une source Arc4, mais plus aléatoire, en ce sens qu'il a un plus longue période jusqu'à la répétition des séquences. Bien que déterministe, c'est pas un hasard cryptographique source. Il est cependant adapté pour obscurcissement des données de jeu.

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)

Exemple tiré de L'exemple de code D'Apple: https://github.com/carekit-apple/CareKit/blob/master/CareKitPrototypingTool/OCKPrototyper/CareKitPatient/RandomNumberGeneratorHelper.swift

0
répondu Steve Moser 2018-08-31 17:02:04

Regardez, j'ai eu le MÊME PROBLÈME MAIS j'insère la fonction en tant que variable globale

Comme

var RNumber = Int(arc4random_uniform(9)+1)

func GetCase(){

your code
}

Évidemment, ce N'est pas efficace, alors je viens de copier et coller le code dans la fonction pour qu'il puisse être réutilisable, alors xcode me suggère de définir la var comme constante pour que mon code soit

func GetCase() {

let RNumber = Int(arc4random_uniform(9)+1)

   if categoria == 1 {
    }
}

Eh bien, c'est une partie de mon code, donc xcode me dit quelque chose d'inmutable et d'initialisation mais, il construit l'application de toute façon et ce conseil disparaît simplement

J'espère que ça aide

-2
répondu Parada11.04 2015-09-18 20:27:33