Swift ile rastgele sayılar üretmek


92

Rastgele bir sayı oluşturmam gerekiyor.

Görünüşe göre arc4randomişlevin yanı sıra arc4random_uniformişlev artık mevcut değil .

Ben seçenekler arc4random_stir(), arc4random_buf(UnsafeMutablePointer<Void>, Int)ve arc4random_addrandom(UnsafeMutablePointer<UInt8>, Int32).

İşlevler hakkında herhangi bir belge bulamıyorum ve başlık dosyalarındaki hiçbir yorum ipucu vermiyor.


3
Görünüşe göre Xcode'daki otomatik tamamlama henüz bozuktu. Otomatik tamamlama olmadan yazdığıma ve derlemediğime yemin edebilirdim. Şimdi çalışıyor. @Arsen tarafından güzel referans
Big_Mac

1
arc4random_uniform mevcuttur. Dilin yerel bir parçası değil, Foundation API'nin bir parçasıdır, bu nedenle, dosyayı kullanılabilir hale getirmek için dosyanın başında bir "Import Foundation" (veya "Import UIKit") gerekir.
Vince O'Sullivan

olasılık = Int (arc4random_uniform (UInt32 (toplam))) - tipönden bozuk olduğu için yazım şikayetleri spesifik değildi, bu benim iki farklı hatadan kaynaklanan döküm şikayetimdi
bshirley

Yanıtlar:


227

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

Kaputun altında Swift arc4random_bufişi bitirmek için kullanıyor .

===== Swift 4.1 / Xcode 9 =====

arc4random()0 ile 4 294 967 295 aralığında rastgele bir sayı döndürür

drand48()0.0 - 1.0 aralığında rastgele bir sayı döndürür

arc4random_uniform(N)0 ile N - 1 aralığında rastgele bir sayı döndürür

Örnekler:

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üst sınır ikinin kuvveti olmadığında "modulo sapmasını " önlediği gibi yapılara göre önerilir .


Float.random()Şu anda işaretlenmiş Beta ve böylece verir'Float' has no member 'random'
Dale

22

Sen de deneyebilirsin:

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

Çalışması için "UInt32" eklemek zorunda kaldım.


1
Bu işleve baktığımda görüyorum public func arc4random_uniform(_: UInt32) -> UInt32. Öyleyse merak ediyorum neden parametreye dönüştürelim UInt32? Burada başka bir şey mi oluyor?
Mark Moeykens

8

Sadece bu işlevi çağırın ve minimum ve maksimum sayı aralığı sağlayın ve rastgele bir sayı alacaksınız.

ör. randomNumber (MIN: 0, MAX: 10) gibi ve 0 ile 9 arasında bir sayı alırsınız .

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

Not: - Her zaman bir Tamsayı çıktısı alacaksınız.


1
Sanırım şöyle olmalı: func randomNumber(MIN: Int, MAX: Int)-> Int{ return Int(arc4random_uniform(UInt32(MAX-MIN)) + UInt32(MIN)); }
Adahus

5

Biraz araştırdıktan sonra şunu yazdım:

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

Şimdi sadece Math.randomFraction()tohumlamayı hatırlamak zorunda kalmadan rastgele sayılar [0..1 [] elde etmek için yapabilirsiniz . Umarım bu birine yardımcı olur: o)


4

Swift 4.2 ile güncelleme:

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)

3

Diğer bir seçenek de xorshift128plus algoritmasını kullanmaktır :

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
}

Bu algoritmanın periyodu 2 ^ 128 - 1'dir ve BigCrush test paketinin tüm testlerini geçer . Bu, uzun süreli yüksek kaliteli bir sözde rastgele sayı üreteci olsa da, şifreleme açısından güvenli bir rasgele sayı üreteci olmadığını unutmayın .

Onu şimdiki zamandan veya herhangi bir rastgele entropi kaynağından tohumlayabilirsiniz. Eğer adlı bir işlev olsaydı Örneğin, urand64()bir okuma UInt64gelen /dev/urandom, bunu şöyle kullanabilirsiniz:

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

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

Neden bu kod için bir açıklama sunmuyorsunuz?
yeniden düzenlendi

1

Swift 3'te:

Sınırlamak için 0 arasında rastgele sayı üretecektir

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

ve 0'dan n'ye kadar değil, 5'ten 10'a kadar rastgele bir sayı üretmek
istersem

1
@Rishi 5'ten 10'a kadar olabilirarc4random_uniform(6) + 5
Matt Le Fleur

1

Int uzantısı olarak benim uygulamam. Aralıkta rastgele sayılar üretecekfrom..<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

Bu şekilde 2 int arasında rastgele bir sayı elde ederim!

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

kullanım:

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

1

Başka bir seçenek de GameKit'ten GKMersenneTwisterRandomSource'u kullanmaktır . Dokümanlar şöyle diyor:

Bir mersenne twister algoritmasına dayalı olarak rastgele sayılar üreten deterministik bir sözde rastgele kaynak. Bu, güvenilir oyun mekaniği oluşturmak için uygun, belirleyici bir rastgele kaynaktır. Bir Arc4 kaynağından biraz daha yavaştır, ancak daha rastgeledir, çünkü tekrarlanan dizilere kadar daha uzun bir süre vardır. Belirleyici olsa da, bu bir kriptografik rastgele kaynak değildir. Bununla birlikte, oyun verilerinin gizlenmesi için uygundur.

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)

Apple'ın örnek kodundan alınan örnek: https://github.com/carekit-apple/CareKit/blob/master/CareKitPrototypingTool/OCKPrototyper/CareKitPatient/RandomNumberGeneratorHelper.swift


1

Partiye geç kaldım 🤩🎉

Dizinin boyutunu ve aralık seçimini anında değiştirmenize izin veren bir işlevi kullanmak en çok yönlü yöntemdir. Ayrıca haritayı da kullanabilirsiniz, böylece çok kısa olur. Bunu tüm performans testlerimde / kıyaslamamda kullanıyorum.

elementsdizideki öğelerin sayısıdır
yalnızca0...max

func randArr(_ elements: Int, _ max: Int) -> [Int] {
        return (0..<elements).map{ _ in Int.random(in: 0...max) }
    }

Kod Algılama / Yer Tutucular şuna benzer. randArr(elements: Int, max: Int)

Dizimde 0 ile 1000 arasında değişen 10 eleman.

randArr(10, 1000) // [554, 8, 54, 87, 10, 33, 349, 888, 2, 77]

0

bunu belirli oranda kullanabilirsiniz:

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

Rastgele sayı veya rastgele dizge için Swift ile Kod Yazalım :)

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

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

size rastgele çıktı verecektir.


0

Bazı sayıların tekrar edeceğini unutmayın! yani şunun gibi bir şey yapmalısın ...

toplam soru 47 idi.

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

}

-2

Bak, aynı problemi yaşadım ama işlevi global değişken olarak ekliyorum

gibi

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

func GetCase(){

your code
}

açıkçası bu etkili değil, bu yüzden kodu kopyalayıp işleve yapıştırıyorum, böylece yeniden kullanılabilir, sonra xcode bana var'ı sabit olarak ayarlamamı önerdi, böylece kodum

func GetCase() {

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

   if categoria == 1 {
    }
}

peki bu benim kodumun bir parçası, bu yüzden xcode bana değişmez ve başlatma ile ilgili bir şeyler söylüyor ama yine de uygulamayı oluşturuyor ve bu tavsiye basitçe kayboluyor

Umarım yardımcı olur

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.