class Quotient

Attributes

a[RW]
abs1[RW]
b[RW]
deltaIter[RW]
denominator[RW]
numerator[RW]

Public Class Methods

new!(a, b = 1) click to toggle source
# File lib/m500.rb, line 1549
def Quotient.new!(a, b = 1)
  if a.kind_of?(Quotient) && b == 1
    a
  else
    new(a, b)
  end
end

Private Class Methods

new(a, b) click to toggle source
# File lib/m500.rb, line 1556
  def initialize(a, b)
    @to_Dec
    if a < 0 or b < 0 then
      a = -1*a if a < 0
      a = -1*b if b < 0
      @abs1 = -1
    elsif (a>= 0 and b >= 0) or (a<0 and b<0) 
      a = -1*a if (a<0 and b<0) 
      b = -1*b if (a<0 and b<0)
      @abs1 = 1
    end
    if b==0 then
# this should have been caught in def Quotient
    end
    if a.kind_of?(Numeric) and b.kind_of?(Numeric)
      a.kind_of?(Zahlen) ? @a = a : @a = Zahlen(a.to_i)
      b.kind_of?(Natural) ? @b = b : @b = Natural(b.to_i)
      unless  a == Zahlen(0) or a==0 or a == naught then
        gcd = Natural(a).gcd(b)
        @numerator = @a.div(gcd) 
        @denominator = @b.div(gcd)
      else
        @numerator = 0
        @denominator = 1
      end
      @setdelta = false
      @deltaIter = 10
      @remainders = []
      @reg2 = []
    end
  end

Public Instance Methods

%(other) click to toggle source
# File lib/m500.rb, line 1707
def % (other)
  value = (self / other).to_i
  return self - other * value
end
*(a) click to toggle source
# File lib/m500.rb, line 1641
def * (a)
  if a == 0 or ( @numerator == 0 and @denominator == 1)
    return Quotient(0,1)
  elsif a.kind_of?(Quotient)
    abs = @abs1 * a.abs1
    num = @numerator * a.numerator
    den = @denominator * a.denominator
    Quotient(num*abs, den)
  elsif a.kind_of?(NaughtClass) or a.kind_of?(EmptySetClass)
    naught
  elsif a.kind_of?(NANClass) or a.kind_of?(InfinityClass)
    infinity
  elsif (a.kind_of?(Zahlen) or a.kind_of?(Counting) or a.kind_of?(Natural) or a.kind_of?(Integer)) #a.kind_of?(Bignum) or a.kind_of?(Fixnum))
    if a ==1 then
      self
    else
      self * Quotient(a, 1)
    end
  elsif a.kind_of?(Float)
    self * a.to_Q
  else
    x, y = a.coerce(self)
    x * y
  end
end
**(other) click to toggle source
# File lib/m500.rb, line 1684
def ** (other)
  if other.kind_of?(Quotient)
    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
    tmp = Quotient.new!(num, den)
    Quotient(tmp.numerator,tmp.denominator)
  elsif other.kind_of?(Float)
    Float(self) ** other
  else
    x, y = other.coerce(self)
    x ** y
  end
end
+(a) click to toggle source
# File lib/m500.rb, line 1593
def + (a)
  if a == 0
    return self
  elsif @numerator == 0 and @denominator == 1
    return a.to_Q
  elsif a.kind_of?(Fraction)
    self + a.to_Q 
  elsif a.kind_of?(Quotient)
    num = (@numerator*@abs1) * (a.denominator)
    num_a = (a.numerator*a.abs1) * @denominator
    Quotient(num + num_a, @denominator * a.denominator)
  elsif a.kind_of?(NaughtClass) or a.kind_of?(EmptySetClass)
    self
  elsif a.kind_of?(NANClass) or a.kind_of?(InfinityClass)
    infinity
  elsif (a.kind_of?(Zahlen) or a.kind_of?(Counting) or a.kind_of?(Natural) or a.kind_of?(Integer)) # a.kind_of?(Bignum) or a.kind_of?(Fixnum))
    self + Quotient(a, 1)
  elsif a.kind_of?(Float)
    Float(self) + a
  else
    x, y = a.coerce(self)
    x + y
  end
end
-(a) click to toggle source
# File lib/m500.rb, line 1617
def - (a)
  if a == 0
    return self
  elsif @numerator == 0 and @denominator == 1
    return a.to_Q
  else
    if a.kind_of?(Quotient)
      num = (@numerator*@abs1) * (a.denominator)
      num_a = (a.numerator*a.abs1) * @denominator
      Quotient(num - num_a, @denominator * a.denominator)
    elsif a.kind_of?(NaughtClass) or a.kind_of?(EmptySetClass) or a == 0
      self
    elsif a.kind_of?(NANClass) or a.kind_of?(InfinityClass)
      infinity*(-1)
    elsif (a.kind_of?(Zahlen) or a.kind_of?(Counting) or a.kind_of?(Natural) or a.kind_of?(Integer)) #a.kind_of?(Bignum) or a.kind_of?(Fixnum))
      self - Quotient.new!(a, 1)
    elsif a.kind_of?(Float)
      Float(self) - a
    else
      x, y = a.coerce(self)
      x - y
    end
  end
end
/(a) click to toggle source
# File lib/m500.rb, line 1666
def / (a)
  if (@numerator == 0 and @denominator == 1)
    return Quotient(0,1)
  elsif a.kind_of?(Quotient)
    abs = @abs1 * a.abs1
    num = @numerator * a.denominator
    den = @denominator * a.numerator
    Quotient(num*abs, den)
  elsif a.kind_of?(Integer)
    raise ZeroDivisionError, "division by zero" if a == 0
    self / Quotient.new!(a, 1)
  elsif a.kind_of?(Float)
    Float(self) / a
  else
    x, y = a.coerce(self)
    x / y
  end
end
<=>(other) click to toggle source
# File lib/m500.rb, line 1740
def <=> (other)
  if @setdelta then
    @@delta = Quotient(((other - self).abs)/@deltaIter) if (other.abs1 == 1 and self.abs1 == 1) or  (other.abs1 == -1 and self.abs1 == -1)
    @@delta = Quotient((Quotient(other.numerator,other.denominator) + Quotient(self.numerator,self.denominator))/@deltaIter) if (other.abs1 == 1 and self.abs1 == -1) or  (other.abs1 == -1 and self.abs1 == 1)
  end
  @setdelta = false
  if other.kind_of?(Quotient)
    num = (@numerator*@abs1) * other.denominator
    num_o = (other.numerator*other.abs1) * @denominator
    v = num- num_o
    if v > 0
      return 1
    elsif v < 0
      return  -1
    else
  return 0
    end
  elsif other.kind_of?(Integer)
    return self <=> Quotient.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
==(other) click to toggle source
# File lib/m500.rb, line 1718
def == (other)
  if other.kind_of?(Quotient)
    @numerator == other.numerator and @denominator == other.denominator
  elsif other.kind_of?(Integer)
    self == Quotient.new!(other, 1)
  elsif other.kind_of?(Float)
    Float(self) == other
  else
    other.to_i == self.to_i
  end
end
===(other) click to toggle source
# File lib/m500.rb, line 1729
def === (other)
  if other.kind_of?(Quotient)
    @a == other.a and @b == other.b
    return 1
  elsif other.kind_of?(Quotient)
    @numerator == other.numerator and @denominator == other.denominator
    return -1
  else
    return 0
  end
end
abs() click to toggle source
# File lib/m500.rb, line 1715
def abs
  @abs1 = -1 ? Quotient.new!(@numerator, @denominator)   : self
end
coerce(other) click to toggle source
# File lib/m500.rb, line 1771
def coerce(other)
  if Natural === other or Counting === other or Zahlen === other
    [Quotient(other,1),self]
  elsif Integer === other #Fixnum === other
    [other, self.to_f]
  else
    [Float(other),self.to_f]
  end
end
diavmod(other) click to toggle source
# File lib/m500.rb, line 1711
def diavmod(other)
  value = (self / other).to_i
  return value, self - other * value
end
hash() click to toggle source
# File lib/m500.rb, line 1848
def hash
  @numerator.hash ^ @denominator.hash ^ @abs.hash
end
inspect() click to toggle source
# File lib/m500.rb, line 1845
def inspect
  @abs1 == -1 ?  sprintf("Quotient(-%s, %s)", @numerator.inspect, @denominator.inspect) :     sprintf("Quotient(%s, %s)", @numerator.inspect, @denominator.inspect)
end
is_0?() click to toggle source
# File lib/m500.rb, line 1780
def is_0?
  @numerator === 0 and  @denominator === 1 ? true : false
end
q2Dec(remainder) click to toggle source
# File lib/m500.rb, line 1805
def q2Dec(remainder)
  maxcount =1000
  kmcount = 0
  ret = nil
  until (@remainders.member?(remainder) and @remainders.index(remainder)!= 0) or (kmcount > maxcount + 100) do 
    break if remainder == 0
    @remainders << remainder
    @reg2 << remainder.div(@denominator.to_i)
    remainder = remainder.remainder(@denominator.to_i)*10 
    kmcount += 1 
  end
 @reg2.shift
  if remainder == 0
    if @abs1 ==1 then
      ret = "Decimal('#{@numerator.div(@denominator)}#{Decimal::decimalSeparator}#{@reg2.join}')"
    elsif @abs1 == -1
      ret = "Decimal('-#{@numerator.div(@denominator)}#{Decimal::decimalSeparator}#{@reg2.join}')"
    end
  else
    @reg2.insert(@remainders.find_index(remainder)-1,"[")  unless (kmcount > maxcount + 100)
    if @abs1 ==1 then
      ret = "Decimal('#{@numerator.div(@denominator)}#{Decimal::decimalSeparator}#{@reg2.join}]')" unless (kmcount > maxcount + 100)
      ret = "Decimal('#{@numerator.div(@denominator)}#{Decimal::decimalSeparator}#{@reg2.join}[0]')" if (kmcount > maxcount + 100)
    elsif @abs1 == -1
      ret = "Decimal('-#{@numerator.div(@denominator)}#{Decimal::decimalSeparator}#{@reg2.join}]')" unless (kmcount > maxcount + 100)
      ret = "Decimal('#{@numerator.div(@denominator)}#{Decimal::decimalSeparator}#{@reg2.join}[0]')" if (kmcount > maxcount + 100)
    end
  end
  eval(ret)
end
setdelta() click to toggle source
# File lib/m500.rb, line 1590
def setdelta
  @setdelta = true
end
succ() click to toggle source
# File lib/m500.rb, line 1768
def succ
  self + @@delta
end
to_Dec() click to toggle source
# File lib/m500.rb, line 1793
def to_Dec
  @to_Dec ||= q2Dec(@numerator.remainder(@denominator))
end
to_Frac() click to toggle source
# File lib/m500.rb, line 1789
def to_Frac
  Fraction(Zahlen(@numerator),Natural(@denominator))
  self >= 0 ? Fraction(Zahlen(@numerator),Natural(@denominator),1) : Fraction(Zahlen(@numerator),Natural(@denominator),-1)
end
to_K() click to toggle source
# File lib/m500.rb, line 1799
def to_K
  Kettenbruch(self.to_Frac)
end
to_Sig() click to toggle source
# File lib/m500.rb, line 1796
def to_Sig
  Sigma(self)
end
to_Z() click to toggle source
# File lib/m500.rb, line 1802
def to_Z
  self.denominator == 1 ? Zahlen(self.numerator) : emptySet
end
to_f() click to toggle source
# File lib/m500.rb, line 1786
def to_f
  @numerator.to_f/@denominator.to_f
end
to_i() click to toggle source
# File lib/m500.rb, line 1783
def to_i
  Integer(@numerator.div(@denominator))
end
to_s() click to toggle source
# File lib/m500.rb, line 1835
def to_s
  "Quotient(#{(@a*@abs1).to_s},#{@b.to_s})"
end
to_s_KM() click to toggle source
# File lib/m500.rb, line 1838
def to_s_KM
  if @b == 1
    (@a*@abs1).to_s
  else
    "#{@numerator*@abs1}/#{@denominator}"
  end
end
to_sgml() click to toggle source
# File lib/m500.rb, line 1546
def to_sgml
  "<mfrac #{sgml_id}class='quotient'><mn>#{@numerator*@abs1}</mn> <mn>#{@denominator}</mn></mfrac>"
end