W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
你需要生成在一定范圍內(nèi)的隨機(jī)數(shù),但你也需要對發(fā)生器進(jìn)行“生成種子”操作來提供可預(yù)測的值。
編寫你自己的隨機(jī)數(shù)生成器。當(dāng)然有很多方法可以做到這一點(diǎn),這里給出一個簡單的示例。 該發(fā)生器絕對不可以以加密為目的!
class Rand
# 如果沒有種子創(chuàng)建,使用當(dāng)前時間作為種子
constructor: (@seed) ->
# Knuth and Lewis' improvements to Park and Miller's LCPRNG
@multiplier = 1664525
@modulo = 4294967296 # 2**32-1;
@offset = 1013904223
unless @seed? && 0 <= seed < @modulo
@seed = (new Date().valueOf() * new Date().getMilliseconds()) % @modulo
# 設(shè)置新的種子值
seed: (seed) ->
@seed = seed
# 返回一個隨機(jī)整數(shù)滿足 0 <= n < @modulo
randn: ->
# new_seed = (a * seed + c) % m
@seed = (@multiplier*@seed + @offset) % @modulo
# 返回一個隨機(jī)浮點(diǎn)滿足 0 <= f < 1.0
randf: ->
this.randn() / @modulo
# 返回一個隨機(jī)的整數(shù)滿足 0 <= f < n
rand: (n) ->
Math.floor(this.randf() * n)
#返回一個隨機(jī)的整數(shù)滿足min <= f < max
rand2: (min, max) ->
min + this.rand(max-min)
JavaScript和CoffeeScript都不提供可產(chǎn)生隨機(jī)數(shù)的發(fā)生器。編寫發(fā)生器對于我們來說將是一個挑戰(zhàn),在于權(quán)衡量的隨機(jī)性與發(fā)生器的簡單性。對隨機(jī)性的全面討論已超出了本書的范圍。如需進(jìn)一步閱讀,可參考Donald Kunth的The Art of Computer Programming第Ⅱ卷第3章的“Random Numbers” ,以及Numerical Recipes in C第二版本第7章的“Random Numbers”。
但是,對于這個隨機(jī)數(shù)發(fā)生器只有簡單的解釋。這是一個線性同余偽隨機(jī)數(shù)發(fā)生器,其運(yùn)行源于一條數(shù)學(xué)公式Ij+1 = (aIj+c) % m,其中a是乘數(shù),c是加法偏移量,m 是模數(shù)。每次請求隨機(jī)數(shù)時就會執(zhí)行很大的乘法和加法運(yùn)算——這里的“很大”與密鑰空間有關(guān)——得到的結(jié)果將以模數(shù)的形式被返回密鑰空間。
這個發(fā)生器的周期為232。雖然它絕對不能以加密為目的,但是對于最簡單的隨機(jī)性要求來說,它是相當(dāng)足夠的。randn()在循環(huán)之前將遍歷整個密鑰空間,下一個數(shù)由上一個來確定。
如果你想修補(bǔ)這個發(fā)生器,強(qiáng)烈建議你去閱讀Knuth的The Art of Computer Programming中的第3章。隨機(jī)數(shù)生成是件很容易弄糟的事情,然而Knuth會解釋如何區(qū)分好的和壞的隨機(jī)數(shù)生成。
不要把發(fā)生器的輸出結(jié)果變成模數(shù)。如果你需要一個整數(shù)的范圍,應(yīng)使用分割的方法。線性同余發(fā)生器的低位是不具有隨機(jī)性的。特別的是,它總是從偶數(shù)種子產(chǎn)生奇數(shù),反之亦然。所以如果你需要一個隨機(jī)的0或者1,不要使用:
# NOT random! Do not do this!
r.randn() % 2
因?yàn)槟憧隙ǖ貌坏诫S機(jī)數(shù)字。反而,你應(yīng)該使用r.rand(2)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: