Lab 11: a Rational class
Exercise
For this problem, devise a Rational
class that
represents a rational number, one that is a quotient of two integers.
Each Rational
object should have two attributes, both of
type int
, its numerator
and its
denominator
. It should have several constructors:
• Rational()
: constructs a rational number with
numerator 0
and denominator 1
.
• Rational(int i)
: constructs a rational number with
numerator i
and denominator 1
.
• Rational(int n, int d)
: constructs a rational number
with numerator n
and denominator d
. You can
assume that d
is a positive integer.
In addition, it should support the following methods:
• Rational plus(Rational that)
: returns the sum of
this
and that
. Recall that the sum of two
fractions is given by:
n1 n2 n1*d2 + n2*d1
---- + ---- = -------------
d1 d2 d1*d2
• Rational minus()
: returns the negation of
this
, i.e. the additive inverse.
n -n
- --- = ---
d d
• Rational minus(Rational that)
: returns the difference
between this
and that
. Use the
plus
and minus
methods just described to write
this one.
• Rational times(Rational that)
: returns the product of
this
and that
. Recall that
n1 n2 n1*n2
---- * ---- = -----
d1 d2 d1*d2
• Rational reciprocal()
: returns a Rational
that is the multiplicative inverse of this
. Write it so
that the new Rational
instance has a positive denominator.
This means that you should flip the signs of both the numerator and the
denominator, if the numerator of this
was negative. You can
assume that the numerator of this
is not 0.
n d
1 / --- = ---
d n
• Rational div(Rational that)
: division of this
this
by that
. Use the times
and
reciprocal
methods just described to write this one.
• std::string to_string()
: a string representing the
Rational
. Some example rational strings include:
-2
2/3
0
-2/3
42
137/17
Write a small program test_rational.cc
with a
main
that tests your Rational
class, similar
to what we did to test the Cmpx
class from lecture.
Optional
GCD
This class works more cleanly if you reduce the numerator and
denominator so that they have no common divisor. You could write a
helper function that computes the greatest common divisor of two
integers and use it in the general constructor, dividing the suggested
numerator and denominator each by their greatest common divisor.
There is a standard way, an algorithm of Euclid, to compute the GCD.
It uses the following fact:
If a ≥ b > 0 then GCD(a,b) =
GCD(b,a - b).
This recurrence eventually leads to a base case of b = 0. In
that case GCD(a,0) = a.
std::string
Constructor
You might enjoy the small challenge of writing an additional constructor
that takes a std::string
, one that looks like the examples
of rational number strings just above, and builds a
Rational
from that string. You could just scan through the
string, looking to see if there is a minus sign in front, reading the
characters looking for a /
, etc.
In doing that work, you could use std::stoi
to convert a
substring to an integer value.