成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

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

整型隨機(jī)數(shù)

如果我們想要一個(gè)整型的隨機(jī)數(shù),則可以考慮用arc4random系列函數(shù)。我們可以通過man arc4random命令來看一下這個(gè)函數(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生成器(請(qǐng)腦補(bǔ)),產(chǎn)生一個(gè)[0, 2^32)區(qū)間的隨機(jī)數(shù)(注意是左閉右開區(qū)間)。這個(gè)函數(shù)的返回類型是UInt32。如下所示:

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

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

  1. arc4random() % 10 // 8 

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

我們?cè)诳刂婆_(tái)中通過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,它接受一個(gè)UInt32類型的參數(shù),指定隨機(jī)數(shù)區(qū)間的上邊界upper_bound,該函數(shù)生成的隨機(jī)數(shù)范圍是[0, upper_bound),如下所示:

  1. arc4random_uniform(10// 6 

而如果想指定區(qū)間的最小值(如隨機(jī)數(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。不過這兩個(gè)函數(shù)有如下幾個(gè)缺點(diǎn):

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

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

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

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

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

64位整型隨機(jī)數(shù)

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

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

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

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

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

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

這個(gè)函數(shù)使用ARC4加密的隨機(jī)數(shù)來填充該函數(shù)第二個(gè)參數(shù)指定的長(zhǎng)度的緩存區(qū)域。因此,如果我們傳入的是sizeof(UInt64),該函數(shù)便會(huì)生成一個(gè)隨機(jī)數(shù)來填充8個(gè)字節(jié)的區(qū)域,并返回給r。那么64位的隨機(jī)數(shù)生成方法便可以如下實(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的實(shí)現(xiàn),大家可以腦補(bǔ)一下。

浮點(diǎn)型隨機(jī)數(shù)

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

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

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

一個(gè)小示例

最近寫了一個(gè)隨機(jī)鍵盤,需要對(duì)0-9這幾個(gè)數(shù)字做個(gè)隨機(jī)排序,正好用上了上面的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() 

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

小結(jié)

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

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

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

2012-03-22 09:31:14

Java

2021-12-27 09:31:20

HashtableJava隨機(jī)數(shù)

2019-09-11 10:09:00

Java虛擬機(jī)算法

2021-06-01 22:31:57

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

2009-12-02 17:01:01

PHP隨機(jī)數(shù)rand()

2010-09-06 17:40:59

SQL函數(shù)

2014-04-25 10:14:39

2023-01-03 07:49:45

Java隨機(jī)數(shù)線程

2009-06-11 15:38:00

Java隨機(jī)數(shù)

2024-11-01 15:51:06

2011-05-24 17:08:57

rand()srand()

2011-07-08 15:11:03

JAVA

2010-10-09 15:35:25

MySQL rand函

2024-01-25 11:32:21

2009-06-11 15:25:39

Java隨機(jī)數(shù)

2010-03-22 19:41:31

2017-05-29 09:56:25

2009-12-08 11:44:14

PHP獲取隨機(jī)數(shù)

2009-06-11 15:16:18

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

2009-12-08 12:58:33

PHP隨機(jī)數(shù)類
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 91精品国产综合久久小仙女图片 | 成人片免费看 | 国产精品视频一区二区三区不卡 | 国产精品一区二区三区四区 | 男人亚洲天堂 | 日韩av一区二区在线观看 | 欧美a区 | 日本电影网站 | 欧美日韩福利视频 | 欧美精品久久 | 久久久久久国产精品久久 | 九色在线 | 亚洲国产成人精品女人久久久 | 天天插天天操 | 亚洲成av人片在线观看 | 欧美性大战久久久久久久蜜臀 | 国产乱码精品一区二三赶尸艳谈 | 成人av电影天堂 | 日韩色在线 | 成人黄色在线观看 | 国产一伦一伦一伦 | 高清黄色| 久久成人18免费网站 | 亚洲综合一区二区三区 | 美女久久久久久久 | 99精品欧美一区二区三区 | 一区二区三区不卡视频 | 在线免费激情视频 | 亚洲高清三级 | 天天操天天射综合网 | 亚洲精品久久久久国产 | 草草草久久久 | 波多野结衣一区二区三区在线观看 | 在线观看中文字幕 | 91精品国产91久久久久久 | 日本亚洲一区 | 国产精品91视频 | 日本午夜网 | 国产日韩欧美一区二区 | 最近日韩中文字幕 | 精品日韩一区 |