Extended maintenance of Ruby versions 1.8.7 and 1.9.2 ended on July 31, 2014. Read more

In Files

  • rational.rb

Class/Module Index [+]

Quicksearch

Rational

Rational implements a rational class for numbers.

A rational number is a number that can be expressed as a fraction p/q where p and q are integers and q != 0. A rational number p/q is said to have numerator p and denominator q. Numbers that are not rational are called irrational numbers. (mathworld.wolfram.com/RationalNumber.html)

To create a Rational Number:

Rational(a,b)             # -> a/b
Rational.new!(a,b)        # -> a/b

Examples:

Rational(5,6)             # -> 5/6
Rational(5)               # -> 5/1

Rational numbers are reduced to their lowest terms:

Rational(6,10)            # -> 3/5

But not if you use the unusual method “new!”:

Rational.new!(6,10)       # -> 6/10

Division by zero is obviously not allowed:

Rational(3,0)             # -> ZeroDivisionError

Attributes

denominator[R]
numerator[R]

Public Class Methods

new(num, den) click to toggle source

This method is actually private.

 
               # File rational.rb, line 102
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
            
new!(num, den = 1) click to toggle source

Implements the constructor. This method does not reduce to lowest terms or check for division by zero. Therefore #Rational() should be preferred in normal use.

 
               # File rational.rb, line 93
def Rational.new!(num, den = 1)
  new(num, den)
end
            
reduce(num, den = 1) click to toggle source

Reduces the given numerator and denominator to their lowest terms. Use Rational() instead.

 
               # File rational.rb, line 71
def Rational.reduce(num, den = 1)
  raise ZeroDivisionError, "denominator is zero" 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
            

Public Instance Methods

%(other) click to toggle source

Returns the remainder when this value is divided by other.

Examples:

r = Rational(7,4)    # -> Rational(7,4)
r % Rational(1,2)    # -> Rational(1,4)
r % 1                # -> Rational(3,4)
r % Rational(1,7)    # -> Rational(1,28)
r % 0.26             # -> 0.19
 
               # File rational.rb, line 257
def % (other)
  value = (self / other).floor
  return self - other * value
end
            
*(a) click to toggle source

Returns the product of this value and a.

Examples:

r = Rational(3,4)    # -> Rational(3,4)
r * 2                # -> Rational(3,2)
r * 4                # -> Rational(3,1)
r * 0.5              # -> 0.375
r * Rational(1,2)    # -> Rational(3,8)
 
               # File rational.rb, line 173
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
            
**(other) click to toggle source

Returns this value raised to the given power.

Examples:

r = Rational(3,4)    # -> Rational(3,4)
r ** 2               # -> Rational(9,16)
r ** 2.0             # -> 0.5625
r ** Rational(1,2)   # -> 0.866025403784439
 
               # File rational.rb, line 220
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
            
+(a) click to toggle source

Returns the addition of this value and a.

Examples:

r = Rational(3,4)      # -> Rational(3,4)
r + 1                  # -> Rational(7,4)
r + 0.5                # -> 1.25
 
               # File rational.rb, line 124
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
            
-(a) click to toggle source

Returns the difference of this value and a. subtracted.

Examples:

r = Rational(3,4)    # -> Rational(3,4)
r - 1                # -> Rational(-1,4)
r - 0.5              # -> 0.25
 
               # File rational.rb, line 148
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
            
/(a) click to toggle source

Returns the quotient of this value and a.

r = Rational(3,4)    # -> Rational(3,4)
r / 2                # -> Rational(3,8)
r / 2.0              # -> 0.375
r / Rational(1,2)    # -> Rational(3,2)
 
               # File rational.rb, line 195
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, "division by zero" 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
            
<=>(other) click to toggle source

Standard comparison operator.

 
               # File rational.rb, line 309
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
            
==(other) click to toggle source

Returns true iff this value is numerically equal to other.

But beware:

Rational(1,2) == Rational(4,8)          # -> true
Rational(1,2) == Rational.new!(4,8)     # -> false

Don’t use ::new!

 
               # File rational.rb, line 294
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
            
abs() click to toggle source

Returns the absolute value.

 
               # File rational.rb, line 277
def abs
  if @numerator > 0
    self
  else
    Rational.new!(-@numerator, @denominator)
  end
end
            
ceil() click to toggle source
 
               # File rational.rb, line 360
def ceil()
  -((-@numerator).div(@denominator))
end
            
coerce(other) click to toggle source
 
               # File rational.rb, line 333
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
            
div(other) click to toggle source
 
               # File rational.rb, line 243
def div(other)
  (self / other).floor
end
            
divmod(other) click to toggle source

Returns the quotient and remainder.

Examples:

r = Rational(7,4)        # -> Rational(7,4)
r.divmod Rational(1,2)   # -> [3, Rational(1,4)]
 
               # File rational.rb, line 269
def divmod(other)
  value = (self / other).floor
  return value, self - other * value
end
            
floor() click to toggle source

Converts the rational to an Integer. Not the nearest integer, the truncated integer. Study the following example carefully:

Rational(+7,4).to_i             # -> 1
Rational(-7,4).to_i             # -> -1
(-1.75).to_i                    # -> -1

In other words:

Rational(-7,4) == -1.75                 # -> true
Rational(-7,4).to_i == (-1.75).to_i     # -> true
 
               # File rational.rb, line 356
def floor()
  @numerator.div(@denominator)
end
            
hash() click to toggle source

Returns a hash code for the object.

 
               # File rational.rb, line 427
def hash
  @numerator.hash ^ @denominator.hash
end
            
inspect() click to toggle source

Returns a reconstructable string representation:

Rational(5,8).inspect     # -> "Rational(5, 8)"
 
               # File rational.rb, line 420
def inspect
  sprintf("Rational(%s, %s)", @numerator.inspect, @denominator.inspect)
end
            
round() click to toggle source
 
               # File rational.rb, line 373
def round()
  if @numerator < 0
    num = -@numerator
    num = num * 2 + @denominator
    den = @denominator * 2
    -(num.div(den))
  else
    num = @numerator * 2 + @denominator
    den = @denominator * 2
    num.div(den)
  end
end
            
to_f() click to toggle source

Converts the rational to a Float.

 
               # File rational.rb, line 389
def to_f
  @numerator.fdiv(@denominator)
end
            
to_i() click to toggle source
Alias for: truncate
to_r() click to toggle source

Returns self.

 
               # File rational.rb, line 411
def to_r
  self
end
            
to_s() click to toggle source

Returns a string representation of the rational number.

Example:

Rational(3,4).to_s          #  "3/4"
Rational(8).to_s            #  "8"
 
               # File rational.rb, line 400
def to_s
  if @denominator == 1
    @numerator.to_s
  else
    @numerator.to_s+"/"+@denominator.to_s
  end
end
            
truncate() click to toggle source
 
               # File rational.rb, line 364
def truncate()
  if @numerator < 0
    return -((-@numerator).div(@denominator))
  end
  @numerator.div(@denominator)
end
            
Also aliased as: to_i

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus