3 # $Release Version: 0.5 $
4 # $Revision: 1.1.1.1.4.1 $
5 # by Keiju ISHITSUKA(SHL Japan Inc.)
18 def Integer.from_prime_division(pd)
20 for prime, index in pd
27 raise ZeroDivisionError if self == 0
33 while (value1, mod = value.divmod(prime)
39 pv.push [prime, count]
41 break if prime * prime >= value
52 # These are included as class variables to cache them for later uses. If memory
53 # usage is a problem, they can be put in Prime#initialize as instance variables.
55 # There must be no primes between @@primes[-1] and @@next_to_check.
56 @@primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
57 # @@next_to_check % 6 must be 1.
58 @@next_to_check = 103 # @@primes[-1] - @@primes[-1] % 6 + 7
59 @@ulticheck_index = 3 # @@primes.index(@@primes.reverse.find {|n|
60 # n < Math.sqrt(@@next_to_check) })
61 @@ulticheck_next_squared = 121 # @@primes[@@ulticheck_index + 1] ** 2
64 # Return the prime cache.
69 alias primes_so_far cache
76 # Return primes given by this instance so far.
78 return @@primes[0, @index + 1]
80 alias primes_so_far primes
84 while @index >= @@primes.length
85 # Only check for prime factors up to the square root of the potential primes,
86 # but without the performance hit of an actual square root calculation.
87 if @@next_to_check + 4 > @@ulticheck_next_squared
88 @@ulticheck_index += 1
89 @@ulticheck_next_squared = @@primes.at(@@ulticheck_index + 1) ** 2
91 # Only check numbers congruent to one and five, modulo six. All others
92 # are divisible by two or three. This also allows us to skip checking against
94 @@primes.push @@next_to_check if @@primes[2..@@ulticheck_index].find {|prime| @@next_to_check % prime == 0 }.nil?
96 @@primes.push @@next_to_check if @@primes[2..@@ulticheck_index].find {|prime| @@next_to_check % prime == 0 }.nil?
99 return @@primes[@index]
104 return to_enum(:each) unless block_given?
127 if other.kind_of?(Rational)
130 return Complex.__send__(:new!, self, 0) ** other
139 npd = numerator.prime_division
140 dpd = denominator.prime_division
147 elm[1] = elm[1] * other
148 if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
149 return Float(self) ** other2
155 elm[1] = elm[1] * other
156 if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
157 return Float(self) ** other2
162 num = Integer.from_prime_division(npd)
163 den = Integer.from_prime_division(dpd)
167 elsif other.kind_of?(Integer)
169 num = numerator ** other
170 den = denominator ** other
172 num = denominator ** -other
173 den = numerator ** -other
179 elsif other.kind_of?(Float)
182 x , y = other.coerce(self)
191 if a.kind_of?(Complex)
192 abs = sqrt(a.real*a.real + a.image*a.image)
193 # if not abs.kind_of?(Rational)
194 # return a**Rational(1,2)
196 x = sqrt((a.real + abs)/Rational(2))
197 y = sqrt((-a.real + abs)/Rational(2))
198 # if !(x.kind_of?(Rational) and y.kind_of?(Rational))
199 # return a**Rational(1,2)
216 elsif a.kind_of?(Rational)
217 rsqrt(a.numerator)/rsqrt(a.denominator)
221 byte_a = [src & 0xffffffff]
223 while (src >= max) and (src >>= 32)
224 byte_a.unshift src & 0xffffffff
231 main = (main << 32) + elm
234 if main * 4 < side * side
235 applo = main.div(side)
237 applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1
240 applo = sqrt!(main).to_i + 1
243 while (x = (side + applo) * applo) > main
247 answer = (answer << 16) + applo
258 module_function :sqrt
259 module_function :rsqrt