Numeric
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
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
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
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
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 253
def % (other)
value = (self / other).to_i
return self - other * value
end
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
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
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
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
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
Standard comparison operator.
# File rational.rb, line 305
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
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 290
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
Returns the absolute value.
# File rational.rb, line 273
def abs
if @numerator > 0
Rational.new!(@numerator, @denominator)
else
Rational.new!(-@numerator, @denominator)
end
end
# File rational.rb, line 329
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
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 265
def divmod(other)
value = (self / other).to_i
return value, self - other * value
end
Returns a hash code for the object.
# File rational.rb, line 395
def hash
@numerator.hash ^ @denominator.hash
end
Returns a reconstructable string representation:
Rational(5,8).inspect # -> "Rational(5, 8)"
# File rational.rb, line 388
def inspect
sprintf("Rational(%s, %s)", @numerator.inspect, @denominator.inspect)
end
Converts the rational to a Float.
# File rational.rb, line 357
def to_f
@numerator.to_f/@denominator.to_f
end
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 # -> -2 (-1.75).to_i # -> -1
In other words:
Rational(-7,4) == -1.75 # -> true Rational(-7,4).to_i == (-1.75).to_i # false
# File rational.rb, line 350
def to_i
Integer(@numerator.div(@denominator))
end
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 see Improve the docs, or visit Documenting-ruby.org.