【问题标题】:Generating random numbers with Swift使用 Swift 生成随机数
【发布时间】:2015-09-13 17:11:05
【问题描述】:

我需要生成一个随机数。

arc4random 函数和 arc4random_uniform 函数似乎不再存在。

我的选项是arc4random_stir()arc4random_buf(UnsafeMutablePointer<Void>, Int)arc4random_addrandom(UnsafeMutablePointer<UInt8>, Int32)

我找不到关于函数的任何文档,并且头文件中没有 cmets 给出提示。

【问题讨论】:

  • Xcode 中的自动完成功能似乎被破坏了。我可以发誓我在没有自动完成的情况下键入它并且它没有编译。现在工作。 @arsen 很好的参考
  • arc4random_uniform 可用。它是 Foundation API 的一部分,而不是语言的原生部分,因此您需要在文件头部添加一个“import Foundation”(或“import UIKit”)以使其可用。
  • probability = Int(arc4random_uniform(UInt32(total))) - 因为预输入被破坏,打字投诉是非具体的,这是我的铸造投诉来自两个不同的错误

标签: swift arc4random


【解决方案1】:
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()

【讨论】:

  • Float.random() 当前标记为 Beta,因此给出 'Float' has no member 'random'
【解决方案2】:

你也可以试试:

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

我必须添加“UInt32”才能使其工作。

【讨论】:

  • 当我查看这个函数时,我看到了public func arc4random_uniform(_: UInt32) -&gt; UInt32。所以我想知道为什么要将参数转换为UInt32?这里发生了其他事情吗?
【解决方案3】:

只要调用这个函数并提供数字的最小和最大范围,你就会得到一个随机数。

eg.like randomNumber(MIN: 0, MAX: 10) 并且您将获得 0 到 9 之间的数字。

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

注意:- 你总是会得到一个整数输出。

【讨论】:

  • 我认为应该是:func randomNumber(MIN: Int, MAX: Int)-&gt; Int{ return Int(arc4random_uniform(UInt32(MAX-MIN)) + UInt32(MIN)); }
【解决方案4】:

经过一番调查,我写了这个:

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)

【讨论】:

    【解决方案5】:

    使用 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)
    

    【讨论】:

      【解决方案6】:

      另一种选择是使用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())
      }
      

      【讨论】:

        【解决方案7】:
        let MAX : UInt32 = 9
        let MIN : UInt32 = 1 
        func randomNumber()
        {
           var random_number = Int(arc4random_uniform(MAX) + MIN)
           print ("random = ", random_number);    
        }
        

        【讨论】:

        • 为什么不解释这段代码?
        【解决方案8】:

        在 Swift 3 中:

        会产生0到限制之间的随机数

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

        【讨论】:

        • 如果我想生成一个从 5 到 10 的随机数,而不是从 0 到 n 的数字
        • @Rishi 从 5 到 10 将是 arc4random_uniform(6) + 5
        【解决方案9】:

        我的实现是一个 Int 扩展。将在from..&lt;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))
            }
        }
        

        【讨论】:

          【解决方案10】:

          这就是我如何获得 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))")
          

          【讨论】:

            【解决方案11】:

            另一种选择是使用 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

            【讨论】:

              【解决方案12】:

              我迟到了 ??

              使用允许您动态更改数组大小和范围选择的函数是最通用的方法。您也可以使用地图,因此非常简洁。我在所有的性能测试/基准测试中都使用它。

              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]
              

              【讨论】:

                【解决方案13】:

                您可以按特定速率使用它:

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

                【讨论】:

                  【解决方案14】:

                  让我们用 Swift 编写随机数或随机字符串 :)

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

                  它会给你随机输出。

                  【讨论】:

                    【解决方案15】:

                    不要忘记有些数字会重复!所以你需要做类似......

                    我的总问题是 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
                    
                    }
                    

                    【讨论】:

                      【解决方案16】:

                      看,我有同样的问题,但我插入 函数作为全局变量

                      作为

                      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 告诉我一些不可变和初始化的信息,但它无论如何都会构建应用程序,而该建议只是消失了

                      希望对你有帮助

                      【讨论】:

                        猜你喜欢
                        • 2015-03-14
                        • 2019-07-16
                        • 2014-07-23
                        • 1970-01-01
                        • 2015-11-07
                        • 2013-11-09
                        • 1970-01-01
                        • 2021-05-24
                        • 2014-09-21
                        相关资源
                        最近更新 更多