May 09, 2021 CoffeeScript
You need to generate random numbers in a range, but you also need to "seed" the generator to provide predictable values.
Write your own random number generator. O f course there are many ways to do this, and here's a simple example. se!
class Rand
# 如果没有种子创建,使用当前时间作为种子
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
# 设置新的种子值
seed: (seed) ->
@seed = seed
# 返回一个随机整数满足 0 <= n < @modulo
randn: ->
# new_seed = (a * seed + c) % m
@seed = (@multiplier*@seed + @offset) % @modulo
# 返回一个随机浮点满足 0 <= f < 1.0
randf: ->
this.randn() / @modulo
# 返回一个随机的整数满足 0 <= f < n
rand: (n) ->
Math.floor(this.randf() * n)
#返回一个随机的整数满足min <= f < max
rand2: (min, max) ->
min + this.rand(max-min)
Neither JavaScript and CoffeeScript provide generators that produce random numbers. W riting generators will be a challenge for us, balancing the randomness of quantities with the simplicity of generators. A comprehensive discussion of randomness is beyond the scope of this book. For further reading, refer to "Random Numbers" in Chapter 3 of Donald Kunth's Art of Computer Programming II. volume 3 and "Random Numbers" in Chapter 7 of the second edition of Numerical Recipes in C.
However, there is only a simple explanation for this random number generator. T his is a linear pseudo-random number generator that runs from a mathematical formula, I j-1 , (aI j-c) % m, where a is the multiplier, c is the addition offset, and m is the mod. Each time a random number is requested, a large multiplication and addition operation is performed - the "large" here is related to the key space - and the result is returned to the key space in the form of a module.
The cycle of this generator is 232. A lthough it can never be used for encryption purposes, it is sufficient for the simplest randomness requirements. Randn() traverses the entire key space before looping, and the next number is determined by the previous one.
If you want to patch this generator, it is highly recommended that you read Chapter 3 of Knuth's The Art of Computer Programming. Random number generation is an easy thing to mess with, but Knuth explains how to distinguish between good and bad random number generation.
Do not turn the output of the generator into modules. I f you need a range of integers, you should use the split method. T he low level of the linear isosotor generator is not random. I n particular, it always produces odd numbers from even seeds, and vice versa. So if you need a random 0 or 1, don't use:
# NOT random! Do not do this!
r.randn() % 2
Because you certainly don't get random numbers. Instead, you should use r.rand (2).