Class: Random::RandomNumberGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/random/random_number_generator.rb

Overview

Abstract Base class for Random Number Generators. The default values for the methods is to work as for a generator giving 32 random bits for each call to next, but there is no requirement that sub-classes must obey this.

Constant Summary collapse

MAX_32BIT_UNSIGNED =
(2**32)-1
FloatMultiplier =
(1.0/4294967295.0)
FloatMultiplierExclusive =
(1.0/4294967296.0)

Instance Method Summary collapse

Constructor Details

#initialize(seed) ⇒ RandomNumberGenerator

Initialize a random number generator given a seed. The seed is either an integer or an array of integers.



9
# File 'lib/random/random_number_generator.rb', line 9

def initialize(seed); end

Instance Method Details

#gen_uint32Object

Generate a 32 bit integer in (0..(2**32 - 1)). This implementation assumes the next method generates exactly this; BEWARE that for generators where this is not true you should override this method.



42
# File 'lib/random/random_number_generator.rb', line 42

def gen_uint32; self.next; end

#maxObject

Returns the maximum value that can be returned by a call to next. Default is MAX_32BIT_UNSIGNED.



19
# File 'lib/random/random_number_generator.rb', line 19

def max; MAX_32BIT_UNSIGNED; end

#minObject

Returns the minimum value that can be returned by a call to next. Default is 0.



13
# File 'lib/random/random_number_generator.rb', line 13

def min; 0; end

#nextObject

Generate the next random number in this PRNG stream. All numbers in (min..max) are equally likely.

Raises:

  • (NotImplementedError)


37
# File 'lib/random/random_number_generator.rb', line 37

def next; raise NotImplementedError; end

#num_random_bitsObject

Max number of random bits returned in a call to next.



22
23
24
# File 'lib/random/random_number_generator.rb', line 22

def num_random_bits
  @num_random_bits ||= (Math.log(1 + max - min)/Math.log(2)).floor
end

#num_random_bytesObject

Max number of random bytes returned in a call to next.



27
28
29
# File 'lib/random/random_number_generator.rb', line 27

def num_random_bytes
  @num_random_bytes ||= (num_random_bits / 8)
end

#rand(max = 0) ⇒ Object

Same as Ruby’s standard rand method.

Converts max to an integer using max1 = max.to_i.abs. If the result is zero, returns a floating point number >= 0.0 and < 1.0. Otherwise, returns an integer >= 0 and < max1.



127
128
129
130
131
132
133
134
# File 'lib/random/random_number_generator.rb', line 127

def rand(max = 0)
  max1 = max.to_i.abs
  if max1 == 0
    rand_float_exclusive
  else
    rand_int_limited(max1 - 1)
  end
end

#rand_bytes(numBytes) ⇒ Object

Return a string with _numBytes random bytes.



144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/random/random_number_generator.rb', line 144

def rand_bytes(numBytes)
  str, index = " " * numBytes, 0
  while index < numBytes
    r = self.next
    [numBytes-index, num_random_bytes].min.times do
      str[index] = r & 0xff
      r >>= 8
      index += 1
    end
  end
  str
end

#rand_floatObject

Generate a random float value in (0.0, 1.0) which means that both 0.0 and 1.0 is included in the interval.

post {|res| res.kind_of?(Float)}
post {|res| res >= 0.0}
post {|res| res <= 1.0}


109
110
111
# File 'lib/random/random_number_generator.rb', line 109

def rand_float
  gen_uint32 * FloatMultiplier
end

#rand_float_exclusiveObject

Generate a random float value in (0.0, 1.0( which means that 0.0 is included in the interval while 1.0 is not.

post {|res| res.kind_of?(Float)}
post {|res| res >= 0.0}
post {|res| res < 1.0}


118
119
120
# File 'lib/random/random_number_generator.rb', line 118

def rand_float_exclusive
  gen_uint32 * FloatMultiplierExclusive
end

#rand_int_big_limited(n) ⇒ Object

Generate an integer in (0..n) inclusive, ie including both 0 and n. Same as rand_int_limited but less efficient if n < 2**32.

pre  {|n|   n >= 0}
post {|res| res >= 0 && res <= n}


67
68
69
70
71
72
73
74
# File 'lib/random/random_number_generator.rb', line 67

def rand_int_big_limited(n)
  num_bits = num_bits_to_represent(n)
  r = rand_int_with_bits(num_bits)
  while r > n
    r = rand_int_with_bits(num_bits)
  end
  r
end

#rand_int_limited(n) ⇒ Object

Generate an integer in (0..n) inclusive, ie including both 0 and n.

pre  {|n|   n >= 0}
post {|res| result >= 0 && result <= n}


93
94
95
96
97
98
99
# File 'lib/random/random_number_generator.rb', line 93

def rand_int_limited(n)
  if n >= 2**32
    rand_int_big_limited(n)
  else
    rand_int_small_limited(n)
  end
end

#rand_int_small_limited(n) ⇒ Object

Generate an integer in (0..n) inclusive, ie including both 0 and n. Much faster than rand_int_big_limited.

pre  {|n|   n >= 0 && n < 2**32}
post {|res| res >= 0 && res <= n}


54
55
56
57
58
59
60
61
# File 'lib/random/random_number_generator.rb', line 54

def rand_int_small_limited(n)
  used_bits = mask_for_int(n)
  r = gen_uint32() & used_bits
  while (r > n)
    r = gen_uint32() & used_bits
  end
  r
end

#rand_int_with_bits(numBits) ⇒ Object

Generate an integer with the given number of bits set randomly.

post {|res| res < 2**numBits}


78
79
80
81
82
83
84
85
86
87
88
# File 'lib/random/random_number_generator.rb', line 78

def rand_int_with_bits(numBits)
  num_bits_left = numBits
  r = 0
  while num_bits_left > 0
    new_bits = self.next
    bits_to_use = [num_bits_left, num_random_bits].min
    r = add_bits(r, bits_to_use, new_bits)
    num_bits_left -= bits_to_use
  end
  r
end

#rand_num(a, b) ⇒ Object

Generate a random integer in the range (a..b) inclusive.

pre {a >= 0}
pre {b >= 0 && b >= a}


139
140
141
# File 'lib/random/random_number_generator.rb', line 139

def rand_num(a, b)
  a + rand_int_limited(b - a)
end