1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/lib/mathn.rb
yugui fce093432e * lib/mathn.rb (Integer): moved into prime.rb.
(Prime): ditto.

* lib/prime.rb (Integer): moved from mathn.rb.
  (Integer.each_prime): added.
  (Integer#prime?): added.
  (Prime): moved from mathn.rb.
    Its implmentation was rewritten. see [ruby-dev:35863].
    And patched by Keiju ISHITSUKA <keiju@ishitsuka.com>,
    see [ruby-dev:36128].
  (Prime.new):                     obsolete.
  (Prime.instance):                added.
  (Prime.each):                    added.
  (Prime.int_from_prime_division): added.
  (Prime.prime_division):          added.
  (Prime.prime?):                  added.
    Patch by TOYOFUKU Chikanobu
    <nobu_toyofuku at nifty.com> in [ruby-dev:36067].
  (Prime.cache):                   removed.
  (Prime.primes):                  removed.
  (Prime.primes_so_far):           removed.
  (Prime#int_from_prime_division): added.
  (Prime#prime_division):          added.
  (Prime#prime?):                  added.
  (Prime#primes):                  removed.
  (Prime#primes_so_far):           removed.
  (Prime::PseudoPrmeGenerator):    added.
  (Prime::EratosthenesGenerator):  added.
  (Prime::TrialDivisionGenerator): added.
  (Prime::Generator23):            added.
  (Prime::TrialDivision):          added.
    Extracted from the previous implementation of Prime
    by Keiju ISHITSUKA.
  (Prime::EratosthenesSieve):      added.

* lib/.document (prime.rb): added

* lib/README (prime.rb): added

* test/test_prime.rb: added.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19095 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-03 13:57:21 +00:00

170 lines
3.1 KiB
Ruby

#
# mathn.rb -
# $Release Version: 0.5 $
# $Revision: 1.1.1.1.4.1 $
# by Keiju ISHITSUKA(SHL Japan Inc.)
#
# --
#
#
#
require "complex.rb"
require "rational.rb"
require "matrix.rb"
require "prime.rb"
class Fixnum
remove_method :/
alias / quo
end
class Bignum
remove_method :/
alias / quo
end
class Rational
Unify = true
alias power! **
def ** (other)
if other.kind_of?(Rational)
other2 = other
if self < 0
return Complex.__send__(:new!, self, 0) ** other
elsif other == 0
return Rational(1,1)
elsif self == 0
return Rational(0,1)
elsif self == 1
return Rational(1,1)
end
npd = numerator.prime_division
dpd = denominator.prime_division
if other < 0
other = -other
npd, dpd = dpd, npd
end
for elm in npd
elm[1] = elm[1] * other
if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
return Float(self) ** other2
end
elm[1] = elm[1].to_i
end
for elm in dpd
elm[1] = elm[1] * other
if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
return Float(self) ** other2
end
elm[1] = elm[1].to_i
end
num = Integer.from_prime_division(npd)
den = Integer.from_prime_division(dpd)
Rational(num,den)
elsif other.kind_of?(Integer)
if other > 0
num = numerator ** other
den = denominator ** other
elsif other < 0
num = denominator ** -other
den = numerator ** -other
elsif other == 0
num = 1
den = 1
end
Rational(num, den)
elsif other.kind_of?(Float)
Float(self) ** other
else
x , y = other.coerce(self)
x ** y
end
end
end
module Math
remove_method(:sqrt)
def sqrt(a)
if a.kind_of?(Complex)
abs = sqrt(a.real*a.real + a.image*a.image)
# if not abs.kind_of?(Rational)
# return a**Rational(1,2)
# end
x = sqrt((a.real + abs)/Rational(2))
y = sqrt((-a.real + abs)/Rational(2))
# if !(x.kind_of?(Rational) and y.kind_of?(Rational))
# return a**Rational(1,2)
# end
if a.image >= 0
Complex(x, y)
else
Complex(x, -y)
end
elsif a >= 0
rsqrt(a)
else
Complex(0,rsqrt(-a))
end
end
def rsqrt(a)
if a.kind_of?(Float)
sqrt!(a)
elsif a.kind_of?(Rational)
rsqrt(a.numerator)/rsqrt(a.denominator)
else
src = a
max = 2 ** 32
byte_a = [src & 0xffffffff]
# ruby's bug
while (src >= max) and (src >>= 32)
byte_a.unshift src & 0xffffffff
end
answer = 0
main = 0
side = 0
for elm in byte_a
main = (main << 32) + elm
side <<= 16
if answer != 0
if main * 4 < side * side
applo = main.div(side)
else
applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1
end
else
applo = sqrt!(main).to_i + 1
end
while (x = (side + applo) * applo) > main
applo -= 1
end
main -= x
answer = (answer << 16) + applo
side += applo * 2
end
if main == 0
answer
else
sqrt!(a)
end
end
end
module_function :sqrt
module_function :rsqrt
end
class Complex
Unify = true
end