簡體   English   中英

使用Swift生成隨機數

[英]Generating random numbers with 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()

arc4random_buf ,Swift使用arc4random_buf完成工作。

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

arc4random()返回在0范圍內的隨機數到4 294 967 295

drand48()返回0.01.0范圍內的隨機數

arc4random_uniform(N)返回0N-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因為它避免了“模數偏壓”的時候,上限不是二的冪。

您也可以嘗試:

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

我必須添加“ UInt32”以使其工作。

只需調用此函數並提供最小和最大范圍的數字,您將獲得一個隨機數。

例如like randomNumber(MIN:0,MAX:10) ,您將獲得介於0到9之間的數字。

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

注意:-您將始終獲得輸出整數。

經過一番調查,我寫道:

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)

另一個選擇是使用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測試套件的所有測試。 請注意,雖然這是一個周期較長的高質量偽隨機數生成器, 但它不是密碼安全的隨機數生成器

您可以從當前時間或任何其他隨機熵源中播種它。 例如,如果您有一個名為urand64()的函數從/dev/urandom中讀取UInt64 ,則可以這樣使用它:

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

用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)
let MAX : UInt32 = 9
let MIN : UInt32 = 1 
func randomNumber()
{
   var random_number = Int(arc4random_uniform(MAX) + MIN)
   print ("random = ", random_number);    
}

在Swift 3中:

它將生成0到限制之間的隨機數

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

我的實現為Int擴展。 將生成范圍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))
    }
}

這就是我如何獲得2個整數之間的隨機數!

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

用法:

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

您可以按特定的比率使用它:

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

讓我們用Swift編寫隨機數或隨機字符串的代碼:)

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

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

它將給您隨機輸出。

不要忘記一些數字會重復! 所以你需要做類似...

我的總問題是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

}

另一個選擇是使用GameKit中的GKMersenneTwisterRandomSource 文檔說:

確定性偽隨機源,它基於mersenne twister算法生成隨機數。 這是確定性隨機源,適合創建可靠的游戲機制。 它比Arc4來源慢一些,但更隨機,因為它有更長的時間直到重復序列。 盡管是確定性的,但這不是加密隨機源。 但是,它適用於混淆游戲數據。

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的示例代碼的示例: https : //github.com/carekit-apple/CareKit/blob/master/CareKitPrototypingTool/OCKPrototyper/CareKitPatient/RandomNumberGeneratorHelper.swift

我參加聚會遲到了

使用允許您即時更改數組大小和范圍選擇的功能是最通用的方法。 您也可以使用地圖,這樣非常簡潔。 我在所有性能測試/基准測試中都使用了它。

elements是數組中的項目數
僅包括從0...max數字

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

代碼含義/占位符看起來像這樣。 randArr(elements: Int, max: Int)

我數組中的10個元素,范圍從0到1000。

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

看,我有同樣的問題,但是我將函數作為全局變量插入

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

func GetCase(){

your code
}

顯然,這沒有效果,所以我只是將代碼復制並粘貼到函數中,以便可以重復使用,然后xcode建議我將var設置為常量,這樣我的代碼就可以了

func GetCase() {

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

   if categoria == 1 {
    }
}

嗯,這就是我的代碼的一部分,所以xcode告訴我一些不可變和初始化的內容,但是無論如何,它都會構建應用程序,而該建議卻消失了

希望能幫助到你

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM