class RSpec::Core::Backports::Random::MT19937

An implementation of Mersenne Twister MT19937 in Ruby.
@private

def self.[](seed)

def self.[](seed)
  new(convert_seed(seed))
end

def self.convert_seed(seed)

integer, or an Array of 32 bit integers.
Convert an Integer seed of arbitrary size to either a single 32 bit
def self.convert_seed(seed)
  seed = seed.abs
  long_values = []
  begin
    long_values << (seed & PAD_32_BITS)
    seed >>= 32
  end until seed == 0
  # Done to allow any kind of sequence of integers.
  long_values.pop if long_values[-1] == 1 && long_values.size > 1
  long_values.size > 1 ? long_values : long_values.first
end

def initialize(seed)

See seed=
def initialize(seed)
  self.seed = seed
end

def left # It's actually the number of words left + 1, as per MRI...

It's actually the number of words left + 1, as per MRI...
def left # It's actually the number of words left + 1, as per MRI...
  MT19937::STATE_SIZE - @last_read
end

def marshal_dump

def marshal_dump
  [state_as_bignum, left]
end

def marshal_load(ary)

def marshal_load(ary)
  b, left = ary
  @last_read = MT19937::STATE_SIZE - left
  @state = Array.new(STATE_SIZE)
  STATE_SIZE.times do |i|
    @state[i] = b & PAD_32_BITS
    b >>= 32
  end
end

def mask_32_bits(n)

def mask_32_bits(n)
  MASK_BY.each do |shift|
    n |= n >> shift
  end
  n
end

def next_state

Generates a completely new state out of the previous one.
def next_state
  STATE_SIZE.times do |i|
    mix = @state[i] & 0x80000000 | @state[i+1 - STATE_SIZE] & 0x7fffffff
    @state[i] = @state[i+OFFSET - STATE_SIZE] ^ (mix >> 1)
    @state[i] ^= 0x9908b0df if mix.odd?
  end
  @last_read = -1
end

def random_32_bits

Returns a random Integer from the range 0 ... (1 << 32).
def random_32_bits
  next_state if @last_read >= LAST_STATE
  @last_read += 1
  y = @state[@last_read]
  # Tempering
  y ^= (y >> 11)
  y ^= (y << 7) & 0x9d2c5680
  y ^= (y << 15) & 0xefc60000
  y ^= (y >> 18)
end

def random_bytes(nb)

def random_bytes(nb)
  nb_32_bits = (nb + 3) / 4
  random = nb_32_bits.times.map { random_32_bits }
  random.pack("L" * nb_32_bits)[0, nb]
end

def random_float

Generates a random number on [0, 1) with 53-bit resolution.
def random_float
  ((random_32_bits >> 5) * 67108864.0 + (random_32_bits >> 6)) * FLOAT_FACTOR;
end

def random_integer(upto)

Returns an integer within 0...upto.
def random_integer(upto)
  n = upto - 1
  nb_full_32 = 0
  while n > PAD_32_BITS
    n >>= 32
    nb_full_32 += 1
  end
  mask = mask_32_bits(n)
  begin
    rand = random_32_bits & mask
    nb_full_32.times do
      rand <<= 32
      rand |= random_32_bits
    end
  end until rand < upto
  rand
end

def seed=(seed)

No conversion or type checking is done at this level.

used).
or an Array of Integers (of which only the first 32 bits will be
Seed must be either an Integer (only the first 32 bits will be used)
def seed=(seed)
  case seed
  when Integer
    @state = Array.new(STATE_SIZE)
    @state[0] = seed & PAD_32_BITS
    (1..LAST_STATE).each do |i|
      @state[i] = (1812433253 * (@state[i-1]  ^ @state[i-1]>>30) + i)& PAD_32_BITS
    end
    @last_read = LAST_STATE
  when Array
    self.seed = 19650218
    i=1
    j=0
    [STATE_SIZE, seed.size].max.times do
      @state[i] = (@state[i] ^ (@state[i-1] ^ @state[i-1]>>30) * 1664525) + j + seed[j] & PAD_32_BITS
      if (i+=1) >= STATE_SIZE
        @state[0] = @state[-1]
        i = 1
      end
      j = 0 if (j+=1) >= seed.size
    end
    (STATE_SIZE-1).times do
      @state[i] = (@state[i] ^ (@state[i-1] ^ @state[i-1]>>30) * 1566083941) - i & PAD_32_BITS
      if (i+=1) >= STATE_SIZE
        @state[0] = @state[-1]
        i = 1
      end
    end
    @state[0] = 0x80000000
  else
    raise ArgumentError, "Seed must be an Integer or an Array"
  end
end

def state_as_bignum

def state_as_bignum
  b = 0
  @state.each_with_index do |val, i|
    b |= val << (32 * i)
  end
  b
end