module Backports::Random::Implementation
Implementation
corresponding to the actual Random
class of Ruby The actual random generator (mersenne twister) is in MT19937
. Ruby specific conversions are handled in bits_and_bytes. The high level stuff (argument checking) is done here.
Attributes
seed[R]
Public Class Methods
new(seed = 0)
click to toggle source
Calls superclass method
# File lib/backports/random/implementation.rb, line 15 def initialize(seed = 0) super() srand(seed) end
Public Instance Methods
==(other)
click to toggle source
# File lib/backports/random/implementation.rb, line 47 def ==(other) other.is_a?(::Random) && seed == other.seed && left == other.send(:left) && state == other.send(:state) end
bytes(nb)
click to toggle source
# File lib/backports/random/implementation.rb, line 41 def bytes(nb) nb = Backports.coerce_to_int(nb) raise ArgumentError, "negative size" if nb < 0 @mt.random_bytes(nb) end
marshal_dump()
click to toggle source
# File lib/backports/random/implementation.rb, line 54 def marshal_dump @mt.marshal_dump << @seed end
marshal_load(ary)
click to toggle source
# File lib/backports/random/implementation.rb, line 58 def marshal_load(ary) @seed = ary.pop @mt = MT19937.allocate @mt.marshal_load(ary) end
rand(limit = Backports::Undefined)
click to toggle source
# File lib/backports/random/implementation.rb, line 27 def rand(limit = Backports::Undefined) case limit when Backports::Undefined @mt.random_float when Float limit * @mt.random_float unless limit <= 0 when Range _rand_range(limit) else limit = Backports.coerce_to_int(limit) @mt.random_integer(limit) unless limit <= 0 end || raise(ArgumentError, "invalid argument #{limit}") end
srand(new_seed = 0)
click to toggle source
# File lib/backports/random/implementation.rb, line 20 def srand(new_seed = 0) new_seed = Backports.coerce_to_int(new_seed) old, @seed = @seed, new_seed.nonzero? || ::Random.new_seed @mt = MT19937[ @seed ] old end
Private Instance Methods
_rand_range(limit)
click to toggle source
# File lib/backports/random/implementation.rb, line 73 def _rand_range(limit) range = limit.end - limit.begin if (!range.is_a?(Float)) && range.respond_to?(:to_int) && range = Backports.coerce_to_int(range) range += 1 unless limit.exclude_end? limit.begin + @mt.random_integer(range) unless range <= 0 elsif range = Backports.coerce_to(range, Float, :to_f) if range < 0 nil elsif limit.exclude_end? limit.begin + @mt.random_float * range unless range <= 0 else # cheat a bit... this will reduce the nb of random bits loop do r = @mt.random_float * range * 1.0001 break limit.begin + r unless r > range end end end end
left()
click to toggle source
# File lib/backports/random/implementation.rb, line 69 def left @mt.left end
state()
click to toggle source
# File lib/backports/random/implementation.rb, line 65 def state @mt.state_as_bignum end