class Prime::EratosthenesSieve
Internal use. An implementation of eratosthenes’s sieve
def extend_table
def extend_table lbound = NUMS_PER_TABLE * @tables.length ubound = lbound + NUMS_PER_TABLE new_table = [FILLED_ENTRY] * ENTRIES_PER_TABLE # which represents primarity in lbound...ubound (3..Integer(Math.sqrt(ubound))).step(2) do |p| j, k = indices(p) t if @tables[i][j][k].zero? rt = (lbound.div(p)+1)*p # least multiple of p which is >= lbound rt += p if start.even? art...ubound).step(2*p) do |n| , j, k = indices(n) ew_table[j] &= FILLED_ENTRY^(1<<k) end @tables << new_table.freeze end
def indices(n)
def indices(n) # binary digits of n: |0|1|2|3|4|5|6|7|8|9|10|11|.... # indices: |-| k | j | i # because of NUMS_PER_ENTRY, NUMS_PER_TABLE k = (n & 0b00011111) >> 1 j = (n & 0b11100000) >> 5 i = n >> 8 return i, j, k end
def initialize # :nodoc:
def initialize # :nodoc: # bitmap for odd prime numbers less than 256. # For an arbitrary odd number n, @tables[i][j][k] is # * 1 if n is prime, # * 0 if n is composite, # where i,j,k = indices(n) @tables = [[0xcb6e, 0x64b4, 0x129a, 0x816d, 0x4c32, 0x864a, 0x820d, 0x2196].freeze] end
def next_to(n)
def next_to(n) n = (n-1).div(2)*2+3 # the next odd number to given n table_index, integer_index, bit_index = indices(n) loop do end_table until @tables.length > table_index j in integer_index...ENTRIES_PER_TABLE f !@tables[table_index][j].zero? for k in bit_index...BITS_PER_ENTRY return NUMS_PER_TABLE*table_index + NUMS_PER_ENTRY*j + 2*k+1 if !@tables[table_index][j][k].zero? end nd it_index = 0 le_index += 1; integer_index = 0 end end