自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Swift 中隨機數(shù)的使用總結(jié)

移動開發(fā)
在我們開發(fā)的過程中,時不時地需要產(chǎn)生一些隨機數(shù)。這里我們總結(jié)一下Swift中常用的一些隨機數(shù)生成函數(shù)。這里我們將在Playground中來做些示例演示。

在我們開發(fā)的過程中,時不時地需要產(chǎn)生一些隨機數(shù)。這里我們總結(jié)一下Swift中常用的一些隨機數(shù)生成函數(shù)。這里我們將在Playground中來做些示例演示。

整型隨機數(shù)

如果我們想要一個整型的隨機數(shù),則可以考慮用arc4random系列函數(shù)。我們可以通過man arc4random命令來看一下這個函數(shù)的定義:

The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be inabout (21700) states. The arc4random() function returns pseudo-random numbers in the range of 0 to (232)-1, and therefore has twice the range of rand(3) and random(3).

arc4random使用了arc4密碼加密的key stream生成器(請腦補),產(chǎn)生一個[0, 2^32)區(qū)間的隨機數(shù)(注意是左閉右開區(qū)間)。這個函數(shù)的返回類型是UInt32。如下所示:

  1. arc4random() // 2,919,646,954 

如果我們想生成一個指定范圍內(nèi)的整型隨機數(shù),則可以使用arc4random() % upper_bound的方式,其中upper_bound指定的是上邊界,如下處理:

  1. arc4random() % 10 // 8 

不過使用這種方法,在upper_bound不是2的冪次方時,會產(chǎn)生一個所謂Modulo bias(模偏差)的問題。

我們在控制臺中通過man arc4random命令,可以查看arc4random的文檔,有這么一條:

arc4random_uniform() will return a uniformly distributed random number less than upper_bound. arc4random_uniform() is recommended over constructions like ‘’arc4random() % upper_bound’‘ as it avoids “modulo bias” when the upper bound is not a power of two.

因此可以使用arc4random_uniform,它接受一個UInt32類型的參數(shù),指定隨機數(shù)區(qū)間的上邊界upper_bound,該函數(shù)生成的隨機數(shù)范圍是[0, upper_bound),如下所示:

  1. arc4random_uniform(10// 6 

而如果想指定區(qū)間的最小值(如隨機數(shù)區(qū)間在[5, 100)),則可以如下處理:

  1. let max: UInt32 = 100 
  2. let min: UInt32 = 5 
  3. arc4random_uniform(max - min) + min // 82 

當(dāng)然,在Swift中也可以使用傳統(tǒng)的C函數(shù)rand與random。不過這兩個函數(shù)有如下幾個缺點:

這兩個函數(shù)都需要初始種子,通常是以當(dāng)前時間來確定。

這兩個函數(shù)的上限在RAND_MAX=0X7fffffff(2147483647),是arc4random的一半。

rand函數(shù)以有規(guī)律的低位循環(huán)方式實現(xiàn),更容易預(yù)測

我們以rand為例,看看其使用:

  1. srand(UInt32(time(nil))) // 種子,random對應(yīng)的是srandom 
  2. rand() // 1,314,695,483 
  3. rand() % 10 // 8 

64位整型隨機數(shù)

在大部分應(yīng)用中,上面講到的幾個函數(shù)已經(jīng)足夠滿足我們獲取整型隨機數(shù)的需求了。不過我們看看它們的函數(shù)聲明,可以發(fā)現(xiàn)這些函數(shù)主要是針對32位整型來操作的。如果我們需要生成一個64位的整型隨機數(shù)呢?畢竟現(xiàn)在的新機器都是支持64位的了。

目前貌似沒有現(xiàn)成的函數(shù)來生成64位的隨機數(shù),不過jstn在stackoverflow上為我們分享了他的方法。我們一起來看看。

他首先定義了一個泛型函數(shù),如下所示:

  1. func arc4random (type: T.Type) -> T { 
  2. var r: T = 0 
  3. arc4random_buf(&r, UInt(sizeof(T))) 
  4. return r 

這個函數(shù)中使用了arc4random_buf來生成隨機數(shù)。讓我們通過man arc4random_buf來看看這個函數(shù)的定義:

arc4random_buf() function fills the region buf of length nbytes with ARC4-derived random data.

這個函數(shù)使用ARC4加密的隨機數(shù)來填充該函數(shù)第二個參數(shù)指定的長度的緩存區(qū)域。因此,如果我們傳入的是sizeof(UInt64),該函數(shù)便會生成一個隨機數(shù)來填充8個字節(jié)的區(qū)域,并返回給r。那么64位的隨機數(shù)生成方法便可以如下實現(xiàn):

  1. extension UInt64 { 
  2. static func random(lower: UInt64 = min, upper: UInt64 = max) -> UInt64 { 
  3. var m: UInt64 
  4. let u = upper - lower 
  5. var r = arc4random(UInt64) 
  6. if u > UInt64(Int64.max) { 
  7. m = 1 + ~u 
  8. else { 
  9. m = ((max - (u * 2)) + 1) % u 
  10. while r < m { 
  11. r = arc4random(UInt64) 
  12. return (r % u) + lower 

我們來試用一下:

  1. UInt64.random() // 4758246381445086013 

當(dāng)然jstn還提供了Int64,UInt32,Int32的實現(xiàn),大家可以腦補一下。

浮點型隨機數(shù)

如果需要一個浮點值的隨機數(shù),則可以使用drand48函數(shù),這個函數(shù)產(chǎn)生一個[0.0, 1.0]區(qū)間中的浮點數(shù)。這個函數(shù)的返回值是Double類型。其使用如下所示:

  1. srand48(Int(time(nil))) 
  2. drand48() // 0.396464773760275 

記住這個函數(shù)是需要先調(diào)用srand48生成一個種子的初始值。

一個小示例

最近寫了一個隨機鍵盤,需要對0-9這幾個數(shù)字做個隨機排序,正好用上了上面的arc4random函數(shù),如下所示:

  1. let arr = ["0""1""2""3""4""5""6""7""8""9"
  2. let numbers = arr.sort { (_, _) -> Bool in 
  3. arc4random() < arc4random() 

在閉包中,隨機生成兩個數(shù),比較它們之間的大小,來確定數(shù)組的排序規(guī)則。還是挺簡單的。

小結(jié)

其實如果翻看一下Swift中關(guān)于C函數(shù)的API,發(fā)現(xiàn)還有許多跟隨機數(shù)相關(guān)的函數(shù),如arc4random_addrandom,erand48等。上面的只是我們經(jīng)常用到的一些函數(shù),這幾個函數(shù)基本上夠用了。當(dāng)然,不同場景有不同的需求,我們需要根據(jù)實際的需求來選擇合適的函數(shù)。

以上的代碼已上傳到github,地址是Random.playground有需要的可以參考一下。

責(zé)任編輯:chenqingxiang 來源: 南峰子的技術(shù)博客
相關(guān)推薦

2012-03-22 09:31:14

Java

2021-12-27 09:31:20

HashtableJava隨機數(shù)

2019-09-11 10:09:00

Java虛擬機算法

2021-06-01 22:31:57

區(qū)塊鏈隨機數(shù)技術(shù)

2009-12-02 17:01:01

PHP隨機數(shù)rand()

2010-09-06 17:40:59

SQL函數(shù)

2014-04-25 10:14:39

2023-01-03 07:49:45

Java隨機數(shù)線程

2009-06-11 15:38:00

Java隨機數(shù)

2024-11-01 15:51:06

2011-05-24 17:08:57

rand()srand()

2011-07-08 15:11:03

JAVA

2024-01-25 11:32:21

2010-10-09 15:35:25

MySQL rand函

2009-06-11 15:25:39

Java隨機數(shù)

2010-03-22 19:41:31

2017-05-29 09:56:25

2009-06-11 15:16:18

不重復(fù)隨機數(shù)Java

2009-12-08 11:44:14

PHP獲取隨機數(shù)

2009-12-08 12:58:33

PHP隨機數(shù)類
點贊
收藏

51CTO技術(shù)棧公眾號