Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[RMXP/VX/Ace] [Herramienta de scripter] Numeric de Keiju Ishitsuka

Ver el tema anterior Ver el tema siguiente Ir abajo

[RMXP/VX/Ace] [Herramienta de scripter] Numeric de Keiju Ishitsuka

Mensaje por Wecoc el 2013-09-29, 22:41

No sé si lo sabéis pero los scripts originales para Ruby de Keiju Ishitsuka son aplicables casi directamente al RPG maker (de hecho solo he tenido que arreglar cuatro tonterías sobre limitaciones del RGSS. Os pongo los tres de Numeric de Keiju Ishitsuke, se usan juntos; separadamente pueden dar errores. Complex, Prime y Rational.

Nota 1: No se puede decir que tenga permiso directo para postear ésto, pero según tengo entendido es código abierto así que no creo que haya problema.

Nota 2: Dad créditos a Keiju Ishitsuka si lo usáis

Complex : permite usar números complejos 5.0 + 1.2i (no se escriben así, mirad el script)

Código:
#
#  complex.rb -
#     $Release Version: 0.5 $
#     $Revision: 1.3 $
#     $Date: 1998/07/08 10:05:28 $
#     by Keiju ISHITSUKA(SHL Japan Inc.)
#
# ----
#
# complex.rb implements the Complex class for complex numbers.  Additionally,
# some methods in other Numeric classes are redefined or added to allow greater
# interoperability with Complex numbers.
#
# Complex numbers can be created in the following manner:
# - <tt>Complex(a, b)</tt>
# - <tt>Complex.polar(radius, theta)</tt>

# Additionally, note the following:
# - <tt>Complex::I</tt> (the mathematical constant <i>i</i>)
# - <tt>Numeric#im</tt> (e.g. <tt>5.im -> 0+5i</tt>)
#
# The following +Math+ module methods are redefined to handle Complex arguments.
# They will work as normal with non-Complex arguments.
#    sqrt exp cos sin tan log log10
#    cosh sinh tanh acos asin atan atan2 acosh asinh atanh
#
#
# Numeric is a built-in class on which Fixnum, Bignum, etc., are based.  Here
# some methods are added so that all number types can be treated to some extent
# as Complex numbers.
#
class Numeric
  # Returns a Complex number <tt>(0,<i>self</i>)</tt>.
  def im
    Complex(0, self)
  end
 
  # The real part of a complex number, i.e. <i>self</i>.
  def real
    self
  end
 
  # The imaginary part of a complex number, i.e. 0.
  def image
    0
  end
  alias imag image
 
  # See Complex#arg.
  def arg
    if self >= 0
      return 0
    else
      return Math::PI
    end
  end
  alias angle arg
 
  # See Complex#polar.
  def polar
    return abs, arg
  end
 
  # See Complex#conjugate (short answer: returns <i>self</i>).
  def conjugate
    self
  end
  alias conj conjugate
end


# Creates a Complex number.  +a+ and +b+ should be Numeric.  The result will be
# <tt>a+bi</tt>.
def Complex(a, b = 0)
  if b == 0 and (a.kind_of?(Complex) or defined? Complex::Unify)
    a
  else
    Complex.new( a.real-b.imag, a.imag+b.real )
  end
end

# The complex number class.  See complex.rb for an overview.
class Complex < Numeric

  undef step

  def Complex.generic?(other) # :nodoc:
    other.kind_of?(Integer) or
    other.kind_of?(Float) or
    (defined?(Rational) and other.kind_of?(Rational))
  end

  # Creates a +Complex+ number in terms of +r+ (radius) and +theta+ (angle).
  def Complex.polar(r, theta)
    Complex(r*Math.cos(theta), r*Math.sin(theta))
  end

  # Creates a +Complex+ number <tt>a</tt>+<tt>b</tt><i>i</i>.
  def Complex.new!(a, b=0)
    new(a,b)
  end

  def initialize(a, b)
    raise TypeError, "non numeric 1st arg `#{a.inspect}'" if !a.kind_of? Numeric
    raise TypeError, "`#{a.inspect}' for 1st arg" if a.kind_of? Complex
    raise TypeError, "non numeric 2nd arg `#{b.inspect}'" if !b.kind_of? Numeric
    raise TypeError, "`#{b.inspect}' for 2nd arg" if b.kind_of? Complex
    @real = a
    @image = b
  end

  # Addition with real or complex number.
  def + (other)
    if other.kind_of?(Complex)
      re = @real + other.real
      im = @image + other.image
      Complex(re, im)
    elsif Complex.generic?(other)
      Complex(@real + other, @image)
    else
      x , y = other.coerce(self)
      x + y
    end
  end
 
  # Subtraction with real or complex number.
  def - (other)
    if other.kind_of?(Complex)
      re = @real - other.real
      im = @image - other.image
      Complex(re, im)
    elsif Complex.generic?(other)
      Complex(@real - other, @image)
    else
      x , y = other.coerce(self)
      x - y
    end
  end
 
  # Multiplication with real or complex number.
  def * (other)
    if other.kind_of?(Complex)
      re = @real*other.real - @image*other.image
      im = @real*other.image + @image*other.real
      Complex(re, im)
    elsif Complex.generic?(other)
      Complex(@real * other, @image * other)
    else
      x , y = other.coerce(self)
      x * y
    end
  end
 
  # Division by real or complex number.
  def / (other)
    if other.kind_of?(Complex)
      self*other.conjugate/other.abs2
    elsif Complex.generic?(other)
      Complex(@real/other, @image/other)
    else
      x, y = other.coerce(self)
      x/y
    end
  end
 
  # Raise this complex number to the given (real or complex) power.
  def ** (other)
    if other == 0
      return Complex(1)
    end
    if other.kind_of?(Complex)
      r, theta = polar
      ore = other.real
      oim = other.image
      nr = Math.exp!(ore*Math.log!(r) - oim * theta)
      ntheta = theta*ore + oim*Math.log!(r)
      Complex.polar(nr, ntheta)
    elsif other.kind_of?(Integer)
      if other > 0
        x = self
        z = x
        n = other - 1
        while n != 0
          while (div, mod = n.divmod(2)
          mod == 0)
            x = Complex(x.real*x.real - x.image*x.image, 2*x.real*x.image)
            n = div
          end
          z *= x
          n -= 1
        end
        z
      else
        if defined? Rational
          (Rational(1) / self) ** -other
        else
          self ** Float(other)
        end
      end
    elsif Complex.generic?(other)
      r, theta = polar
      Complex.polar(r**other, theta*other)
    else
      x, y = other.coerce(self)
      x**y
    end
  end
 
  # Remainder after division by a real or complex number.
  def % (other)
    if other.kind_of?(Complex)
      Complex(@real % other.real, @image % other.image)
    elsif Complex.generic?(other)
      Complex(@real % other, @image % other)
    else
      x , y = other.coerce(self)
      x % y
    end
  end
 
  def divmod(other)
    if other.kind_of?(Complex)
      rdiv, rmod = @real.divmod(other.real)
      idiv, imod = @image.divmod(other.image)
      return Complex(rdiv, idiv), Complex(rmod, rmod)
    elsif Complex.generic?(other)
      Complex(@real.divmod(other), @image.divmod(other))
    else
      x , y = other.coerce(self)
      x.divmod(y)
    end
  end
 
  # Absolute value (aka modulus): distance from the zero point on the complex
  # plane.
  def abs
    Math.hypot(@real, @image)
  end
 
  # Square of the absolute value.
  def abs2
    @real*@real + @image*@image
  end
 
  # Argument (angle from (1,0) on the complex plane).
  def arg
    Math.atan2!(@image, @real)
  end
  alias angle arg
 
  # Returns the absolute value _and_ the argument.
  def polar
    return abs, arg
  end
 
  # Complex conjugate (<tt>z + z.conjugate = 2 * z.real</tt>).
  def conjugate
    Complex(@real, -@image)
  end
  alias conj conjugate
 
  # Compares the absolute values of the two numbers.
  def <=> (other)
    self.abs <=> other.abs
  end
 
  # Test for numerical equality (<tt>a == a + 0<i>i</i></tt>).
  def == (other)
    if other.kind_of?(Complex)
      @real == other.real and @image == other.image
    elsif Complex.generic?(other)
      @real == other and @image == 0
    else
      other == self
    end
  end

  # Attempts to coerce +other+ to a Complex number.
  def coerce(other)
    if Complex.generic?(other)
      return Complex.new!(other), self
    else
      super
    end
  end

  # FIXME
  def denominator
    @real.denominator.lcm(@image.denominator)
  end
 
  # FIXME
  def numerator
    cd = denominator
    Complex(@real.numerator*(cd/@real.denominator),
       @image.numerator*(cd/@image.denominator))
  end
 
  # Standard string representation of the complex number.
  def to_s
    if @real != 0
      if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
        if @image >= 0
          @real.to_s+"+("+@image.to_s+")i"
        else
          @real.to_s+"-("+(-@image).to_s+")i"
        end
      else
        if @image >= 0
          @real.to_s+"+"+@image.to_s+"i"
        else
          @real.to_s+"-"+(-@image).to_s+"i"
        end
      end
    else
      if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
        "("+@image.to_s+")i"
      else
        @image.to_s+"i"
      end
    end
  end
 
  # Returns a hash code for the complex number.
  def hash
    @real.hash ^ @image.hash
  end
 
  # Returns "<tt>Complex(<i>real</i>, <i>image</i>)</tt>".
  def inspect
    sprintf("Complex(%s, %s)", @real.inspect, @image.inspect)
  end

 
  # +I+ is the imaginary number.  It exists at point (0,1) on the complex plane.
  I = Complex(0,1)
 
 
  attr :real # The real part of a complex number.
  attr :image # The imaginary part of a complex number.
  alias imag image
 
end

module Math
  alias sqrt! sqrt
  alias exp! exp
  alias log! log
  alias log10! log10
  alias cos! cos
  alias sin! sin
  alias tan! tan
  alias cosh! cosh
  alias sinh! sinh
  alias tanh! tanh
  alias acos! acos
  alias asin! asin
  alias atan! atan
  alias atan2! atan2
  alias acosh! acosh
  alias asinh! asinh
  alias atanh! atanh 

  # Redefined to handle a Complex argument.
  def sqrt(z)
    if Complex.generic?(z)
      if z >= 0
        sqrt!(z)
      else
        Complex(0,sqrt!(-z))
      end
    else
      if z.image < 0
        sqrt(z.conjugate).conjugate
      else
        r = z.abs
        x = z.real
        Complex( sqrt!((r+x)/2), sqrt!((r-x)/2) )
      end
    end
  end
 
  # Redefined to handle a Complex argument.
  def exp(z)
    if Complex.generic?(z)
      exp!(z)
    else
      Complex(exp!(z.real) * cos!(z.image), exp!(z.real) * sin!(z.image))
    end
  end
 
  # Redefined to handle a Complex argument.
  def cos(z)
    if Complex.generic?(z)
      cos!(z)
    else
      Complex(cos!(z.real)*cosh!(z.image),
         -sin!(z.real)*sinh!(z.image))
    end
  end
   
  # Redefined to handle a Complex argument.
  def sin(z)
    if Complex.generic?(z)
      sin!(z)
    else
      Complex(sin!(z.real)*cosh!(z.image),
         cos!(z.real)*sinh!(z.image))
    end
  end
 
  # Redefined to handle a Complex argument.
  def tan(z)
    if Complex.generic?(z)
      tan!(z)
    else
      sin(z)/cos(z)
    end
  end

  def sinh(z)
    if Complex.generic?(z)
      sinh!(z)
    else
      Complex( sinh!(z.real)*cos!(z.image), cosh!(z.real)*sin!(z.image) )
    end
  end

  def cosh(z)
    if Complex.generic?(z)
      cosh!(z)
    else
      Complex( cosh!(z.real)*cos!(z.image), sinh!(z.real)*sin!(z.image) )
    end
  end

  def tanh(z)
    if Complex.generic?(z)
      tanh!(z)
    else
      sinh(z)/cosh(z)
    end
  end
 
  # Redefined to handle a Complex argument.
  def log(z)
    if Complex.generic?(z) and z >= 0
      log!(z)
    else
      r, theta = z.polar
      Complex(log!(r.abs), theta)
    end
  end
 
  # Redefined to handle a Complex argument.
  def log10(z)
    if Complex.generic?(z)
      log10!(z)
    else
      log(z)/log!(10)
    end
  end

  def acos(z)
    if Complex.generic?(z) and z >= -1 and z <= 1
      acos!(z)
    else
      -1.0.im * log( z + 1.0.im * sqrt(1.0-z*z) )
    end
  end

  def asin(z)
    if Complex.generic?(z) and z >= -1 and z <= 1
      asin!(z)
    else
      -1.0.im * log( 1.0.im * z + sqrt(1.0-z*z) )
    end
  end

  def atan(z)
    if Complex.generic?(z)
      atan!(z)
    else
      1.0.im * log( (1.0.im+z) / (1.0.im-z) ) / 2.0
    end
  end

  def atan2(y,x)
    if Complex.generic?(y) and Complex.generic?(x)
      atan2!(y,x)
    else
      -1.0.im * log( (x+1.0.im*y) / sqrt(x*x+y*y) )
    end
  end

  def acosh(z)
    if Complex.generic?(z) and z >= 1
      acosh!(z)
    else
      log( z + sqrt(z*z-1.0) )
    end
  end

  def asinh(z)
    if Complex.generic?(z)
      asinh!(z)
    else
      log( z + sqrt(1.0+z*z) )
    end
  end

  def atanh(z)
    if Complex.generic?(z) and z >= -1 and z <= 1
      atanh!(z)
    else
      log( (1.0+z) / (1.0-z) ) / 2.0
    end
  end

  module_function :sqrt!
  module_function :sqrt
  module_function :exp!
  module_function :exp
  module_function :log!
  module_function :log
  module_function :log10!
  module_function :log10
  module_function :cosh!
  module_function :cosh
  module_function :cos!
  module_function :cos
  module_function :sinh!
  module_function :sinh
  module_function :sin!
  module_function :sin
  module_function :tan!
  module_function :tan
  module_function :tanh!
  module_function :tanh
  module_function :acos!
  module_function :acos
  module_function :asin!
  module_function :asin
  module_function :atan!
  module_function :atan
  module_function :atan2!
  module_function :atan2
  module_function :acosh!
  module_function :acosh
  module_function :asinh!
  module_function :asinh
  module_function :atanh!
  module_function :atanh
 
end
Mathn : Soporte para Complex y Rational. Prime : Permite usar e identificar números primos.

Código:
#
#  mathn.rb -
#     $Release Version: 0.5 $
#     $Revision: 1.1.1.1.4.1 $
#     $Date: 1998/01/16 12:36:05 $
#     by Keiju ISHITSUKA(SHL Japan Inc.)
#
# --


class Integer

  def gcd2(int)
    a = self.abs
    b = int.abs
    a, b = b, a if a < b
   
    pd_a = a.prime_division
    pd_b = b.prime_division
   
    gcd = 1
    for pair in pd_a
      as = pd_b.assoc(pair[0])
      if as
        gcd *= as[0] ** [as[1], pair[1]].min
      end
    end
    return gcd
  end
 
  def Integer.from_prime_division(pd)
    value = 1
    for prime, index in pd
      value *= prime**index
    end
    value
  end
 
  def prime_division
    ps = Prime.new
    value = self
    pv = []
    for prime in ps
      count = 0
      while (value1, mod = value.divmod(prime)
       mod) == 0
        value = value1
        count += 1
      end
      if count != 0
        pv.push [prime, count]
      end
      break if prime * prime  >= value
    end
    if value > 1
      pv.push [value, 1]
    end
    return pv
  end
end
 
class Prime
  include Enumerable

  def initialize
    @seed = 1
    @primes = []
    @counts = []
  end
 
  def succ
    i = -1
    size = @primes.size
    while i < size
      if i == -1
        @seed += 1
        i += 1
            else
        while @seed > @counts[i]
          @counts[i] += @primes[i]
        end
        if @seed != @counts[i]
          i += 1
        else
          i = -1
        end
      end
    end
    @primes.push @seed
    @counts.push @seed + @seed
    return @seed
  end
  alias next succ

  def each
    loop do
      yield succ
    end
  end
end

class Fixnum
  alias / quo
end

class Bignum
  alias / quo
end

class Rational
  Unify = true

  def inspect
    format "%s/%s", numerator.inspect, denominator.inspect
  end

  def ** (other)
    if other.kind_of?(Rational)
      if self < 0
        return Complex.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) ** other
        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) ** other
        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.new!(num, den)
    elsif other.kind_of?(Float)
      Float(self) ** other
    else
      x , y = other.coerce(self)
      x ** y
    end
  end

  alias power! **
 
  def power2(other)
    if other.kind_of?(Rational)
      if self < 0
        return Complex(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
     
      dem = nil
      x = self.denominator.to_f.to_i
      neard = self.denominator.to_f ** (1.0/other.denominator.to_f)
      loop do
        if (neard**other.denominator == self.denominator)
          dem = neaed
          break
        end
      end
      nearn = self.numerator.to_f ** (1.0/other.denominator.to_f)
      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.new!(num, den)
    elsif other.kind_of?(Float)
      Float(self) ** other
    else
      x , y = other.coerce(self)
      x ** y
    end
  end
end

module Math
  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
Rational : Permite usar fracciones

Código:
#
#  rational.rb -
#     $Release Version: 0.5 $
#     $Revision: 1.7 $
#     $Date: 1999/08/24 12:49:28 $
#     by Keiju ISHITSUKA(SHL Japan Inc.)
#
# --
#  Usage:
#  class Rational < Numeric
#      (include Comparable)
#
#  Rational(a, b) --> a/b
#
#  Rational::+
#  Rational::-
#  Rational::*
#  Rational::/
#  Rational::**
#  Rational::%
#  Rational::divmod
#  Rational::abs
#  Rational::<=>
#  Rational::to_i
#  Rational::to_f
#  Rational::to_s
#
#  Integer::gcd
#  Integer::lcm
#  Integer::gcdlcm
#  Integer::to_r
#
#  Fixnum::**
#  Fixnum::quo
#  Bignum::**
#  Bignum::quo
#

def Rational(a, b = 1)
  if a.kind_of?(Rational) && b == 1
    a
  else
    Rational.reduce(a, b)
  end
end
 
class Rational < Numeric
  @RCS_ID='-$Id: rational.rb,v 1.7 1999/08/24 12:49:28 keiju Exp keiju $-'

  def Rational.reduce(num, den = 1)
    raise ZeroDivisionError, "denominator is 0" if den == 0

    if den < 0
      num = -num
      den = -den
    end
    gcd = num.gcd(den)
    num = num.div(gcd)
    den = den.div(gcd)
    if den == 1 && defined?(Unify)
      num
    else
      new!(num, den)
    end
  end
 
  def Rational.new!(num, den = 1)
    new(num, den)
  end

  private_class_method :new

  def initialize(num, den)
    if den < 0
      num = -num
      den = -den
    end
    if num.kind_of?(Integer) and den.kind_of?(Integer)
      @numerator = num
      @denominator = den
    else
      @numerator = num.to_i
      @denominator = den.to_i
    end
  end
 
  def + (a)
    if a.kind_of?(Rational)
      num = @numerator * a.denominator
      num_a = a.numerator * @denominator
      Rational(num + num_a, @denominator * a.denominator)
    elsif a.kind_of?(Integer)
      self + Rational.new!(a, 1)
    elsif a.kind_of?(Float)
      Float(self) + a
    else
      x, y = a.coerce(self)
      x + y
    end
  end
 
  def - (a)
    if a.kind_of?(Rational)
      num = @numerator * a.denominator
      num_a = a.numerator * @denominator
      Rational(num - num_a, @denominator*a.denominator)
    elsif a.kind_of?(Integer)
      self - Rational.new!(a, 1)
    elsif a.kind_of?(Float)
      Float(self) - a
    else
      x, y = a.coerce(self)
      x - y
    end
  end
 
  def * (a)
    if a.kind_of?(Rational)
      num = @numerator * a.numerator
      den = @denominator * a.denominator
      Rational(num, den)
    elsif a.kind_of?(Integer)
      self * Rational.new!(a, 1)
    elsif a.kind_of?(Float)
      Float(self) * a
    else
      x, y = a.coerce(self)
      x * y
    end
  end
 
  def / (a)
    if a.kind_of?(Rational)
      num = @numerator * a.denominator
      den = @denominator * a.numerator
      Rational(num, den)
    elsif a.kind_of?(Integer)
      raise ZeroDivisionError, "divided by 0" if a == 0
      self / Rational.new!(a, 1)
    elsif a.kind_of?(Float)
      Float(self) / a
    else
      x, y = a.coerce(self)
      x / y
    end
  end
 
  def ** (other)
    if other.kind_of?(Rational)
      Float(self) ** other
    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.new!(num, den)
    elsif other.kind_of?(Float)
      Float(self) ** other
    else
      x, y = other.coerce(self)
      x ** y
    end
  end
 
  def % (other)
    value = (self / other).to_i
    return self - other * value
  end
 
  def divmod(other)
    value = (self / other).to_i
    return value, self - other * value
  end
 
  def abs
    if @numerator > 0
      Rational.new!(@numerator, @denominator)
    else
      Rational.new!(-@numerator, @denominator)
    end
  end

  def == (other)
    if other.kind_of?(Rational)
      @numerator == other.numerator and @denominator == other.denominator
    elsif other.kind_of?(Integer)
      self == Rational.new!(other, 1)
    elsif other.kind_of?(Float)
      Float(self) == other
    else
      other == self
    end
  end

  def <=> (other)
    if other.kind_of?(Rational)
      num = @numerator * other.denominator
      num_a = other.numerator * @denominator
      v = num - num_a
      if v > 0
        return 1
      elsif v < 0
        return  -1
      else
        return 0
      end
    elsif other.kind_of?(Integer)
      return self <=> Rational.new!(other, 1)
    elsif other.kind_of?(Float)
      return Float(self) <=> other
    elsif defined? other.coerce
      x, y = other.coerce(self)
      return x <=> y
    else
      return nil
    end
  end

  def coerce(other)
    if other.kind_of?(Float)
      return other, self.to_f
    elsif other.kind_of?(Integer)
      return Rational.new!(other, 1), self
    else
      super
    end
  end

  def to_i
    Integer(@numerator.div(@denominator))
  end
 
  def to_f
    @numerator.to_f/@denominator.to_f
  end
 
  def to_s
    if @denominator == 1
      @numerator.to_s
    else
      @numerator.to_s+"/"+@denominator.to_s
    end
  end
 
  def to_r
    self
  end
 
  def inspect
    sprintf("Rational(%s, %s)", @numerator.inspect, @denominator.inspect)
  end
 
  def hash
    @numerator.hash ^ @denominator.hash
  end
 
  attr :numerator
  attr :denominator
 
  private :initialize
end

class Integer
  def numerator
    self
  end
 
  def denominator
    1
  end
 
  def to_r
    Rational(self, 1)
  end
 
  def gcd(n)
    m = self.abs
    n = n.abs

    return n if m == 0
    return m if n == 0

    b = 0
    while n[0] == 0 && m[0] == 0
      b += 1; n >>= 1; m >>= 1
    end
    m >>= 1 while m[0] == 0
    n >>= 1 while n[0] == 0
    while m != n
      m, n = n, m if n > m
      m -= n; m >>= 1 while m[0] == 0
    end
    m << b
  end
 
  def gcd2(int)
    a = self.abs
    b = int.abs
 
    a, b = b, a if a < b
 
    while b != 0
      void, a = a.divmod(b)
      a, b = b, a
    end
    return a
  end

  def lcm(int)
    a = self.abs
    b = int.abs
    gcd = a.gcd(b)
    (a.div(gcd)) * b
  end
 
  def gcdlcm(int)
    a = self.abs
    b = int.abs
    gcd = a.gcd(b)
    return gcd, (a.div(gcd)) * b
  end
 
end

class Fixnum
  undef quo
  def quo(other)
    Rational.new!(self,1) / other
  end
  alias rdiv quo
 
  def rpower (other)
    if other >= 0
      self.power!(other)
    else
      Rational.new!(self,1)**other
    end
  end

  unless defined? 1.power!
    alias power! **
    alias ** rpower
  end
end

class Bignum
  unless defined? Complex
    alias power! **
  end

  undef quo
  def quo(other)
    Rational.new!(self,1) / other
  end
  alias rdiv quo
 
  def rpower (other)
    if other >= 0
      self.power!(other)
    else
      Rational.new!(self, 1)**other
    end
  end
 
  unless defined? Complex
    alias ** rpower
  end
end
No deberían daros errores pero tampoco he comprobado el 100% de los métodos. La mayoría de arreglos seran fáciles así que si necesitáis usarlo y os da algún error intentaré solucionarlo.
avatar
Wecoc
Administrador
Administrador



Créditos 12314

Gracias : 655

Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.