File: xor_shift_random.rb

package info (click to toggle)
ruby-thread-safe 0.3.6-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster, forky, sid, trixie
  • size: 712 kB
  • sloc: java: 5,458; ruby: 2,917; makefile: 6
file content (41 lines) | stat: -rw-r--r-- 1,433 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
module ThreadSafe
  module Util
    # A xorshift random number (positive +Fixnum+s) generator, provides
    # reasonably cheap way to generate thread local random numbers without
    # contending for the global +Kernel.rand+.
    #
    # Usage:
    #   x = XorShiftRandom.get # uses Kernel.rand to generate an initial seed
    #   while true
    #     if (x = XorShiftRandom.xorshift).odd? # thread-localy generate a next random number
    #       do_something_at_random
    #     end
    #   end
    module XorShiftRandom
      extend self
      MAX_XOR_SHIFTABLE_INT = MAX_INT - 1

      # Generates an initial non-zero positive +Fixnum+ via +Kernel.rand+.
      def get
        Kernel.rand(MAX_XOR_SHIFTABLE_INT) + 1 # 0 can't be xorshifted
      end

      # xorshift based on: http://www.jstatsoft.org/v08/i14/paper
      if 0.size == 4
        # using the "yˆ=y>>a; yˆ=y<<b; yˆ=y>>c;" transform with the (a,b,c) tuple with values (3,1,14) to minimise Bignum overflows
        def xorshift(x)
          x ^= x >> 3
          x ^= (x << 1) & MAX_INT # cut-off Bignum overflow
          x ^= x >> 14
        end
      else
        # using the "yˆ=y>>a; yˆ=y<<b; yˆ=y>>c;" transform with the (a,b,c) tuple with values (1,1,54) to minimise Bignum overflows
        def xorshift(x)
          x ^= x >> 1
          x ^= (x << 1) & MAX_INT # cut-off Bignum overflow
          x ^= x >> 54
        end
      end
    end
  end
end