Sample Assignment: Cleaning Up the Polynomial Class
|
|
The new work has only one new member function, and one modification to an existing member function.
When you submit this assignment, it will be graded by the TA for correctness and adherance to the items listed below.
assert
.
fill_n
function
from <algorithm
>, as shown here:
fill_n(coef, CAPACITY, 0.0);
current_degree
to zero.
assign_coef
function to set the specified
term.
add_to_coef
assert
.
assign_coef
to change the
specified term in the right way.
clear
current_degree
to
zero.
assign_coef
coef[exponent]
to equal the new coefficient
.
Since this function has change the coef
array, it is now
responsible for making sure that current_degree
is still
correct. There are two cases that you must check:
current_degree
, and the coefficient
is not
zero, then the degree has just increased to exponent
.
current_degree
has been reset
to zero. My suggestion is to handle the resetting with a small
loop. The loop continues as long as the current_degree
is
above zero, and the coef[current_degree]
is equal to
zero. In this case, reduce the current_degree
by
one. Eventually the loop will end (when the
current_degree
drops to zero, or when you find a non-zero
term).
current_degree
coef
array are the constructor,
clear
and
assign_coef
. Because of this, these are also
the only functions that ever need to change the private member
variable current_degree
.
Also, make sure that your degree
function is just one
simple line (return current_degree;
--and since it is
so simple, please move this to an inline function in the header file.
coefficient
MAX_EX
, it must always return the value zero.
coef
and
current_degree
) and two public member constants
(CAPACITY
and MAX_EX
). When you have
implemented the suggestions shown above, you should check that
these variables and constants are directly accessed in only a few
functions (really!). Those functions are:
The constructor
add_to_coef
assign_coef
clear
coefficient
degree
operator *
(but only using MAX_EX
in the
assert
)
next_term
next_term
function.
The new specification uses zero for the return value when there
is no next term. Make this change to your function and to the
documentation in poly0.h
:
unsigned int next_term(unsigned int e) const POSTCONDITION: The return value is the next exponent n which is LARGER than e such that coefficient(n) != 0. If there is no such term, then the return value is zero.By the way, the reason for the choice of zero is that zero cannot otherwise be a valid answer from
next_term
(since there
are no terms before the zero-order term).
previous_term
previous_term
function
to your class and to the
documentation in poly0.h
:
unsigned int previous_term(unsigned int e) const POSTCONDITION: The return value is the next exponent n which is SMALLER than e such that coefficient(n) != 0. If there is no such term, then the return value is UINT_MAX from.
make_gif
make_gif
function
from
www.cs.colorado.edu/~main/chapter3/polygif.cxx. In order to use
this function, you must #include <fstream>
.
operator <<
previous_term
function to greatly
simplify your implementation of the output operator. Here is an
outline of an implementation that should take under 40 lines to
implement:
ostream& operator << (ostream& out, const polynomial& p) { unsigned int i = p.degree( ); double number; // Each iteration of this loop prints one term of the polynomial: do { // Get the coefficient: number = p.coefficient(i); // Print a sign ...there are three possibilities: "-" in front of the first term if it is negative " - " in front of other negative terms " + " in front of positive terms (except if it is first term) // Get rid of any negative sign in the number: number = fabs(number); // Print the number, variable x, and exponent ...print the number only when it is not 1.0 or it is the constant term ...print the letter x only when the exponent is above zero ...print the exponent only when it is above one // Move to the next lowest term: i = p.previous_term(i); } while (i != UINT_MAX); return out; //return the output stream }
unsigned int
unsigned int
.
unsigned int i; i = 0; do { ...code that processes the x^i term.... i = next_term(i); } while (i != 0);For example, the
eval
function can use a loop along these
lines (using the pow
function from
<cmath>
to compute x
to the
i
power:
unsigned int i; double answer = 0; i = 0; do { answer += coefficient(i) * pow(x, i); i = next_term(i); } while (i != 0);Here's a question for you: Why is it important to use a do-while loop in this example, rather than a simple while-loop or for-loop? The answer is that we start the control variable
i
at
i=0
, so that a while-loop or for-loop would
immediately stop (with the condition (i != 0
).
There are some exceptions that can use a simpler loop when it
is okay to start at i=1
instead of i=0
. For
example, the loop in eval
could be done this way instead:
unsigned int i; double answer = coefficient(i); // We have already put the zero term in the answer, so we can // start with the next term after that: for (i = next_term(0); i != 0; i = next_term(i)) { answer += coefficient(i) * pow(x, i); }As another example, in the
derivative
function, you can start i
at one instead of zero. In
derivative
you might also prefer a for-loop such as:
for (i = 1; i != 0; i = next_term(i)) ...set the i-1 term of your answer...What kind of loop will you use in the output operator (shown above) and the loop to lower
current_degree
in the
assign_coef
function?
Finally, the implementations of next_term
and
previous_term
can use some simple for-loops to
find the next or previous term.
assert
at the
top of these functions: The constructor,
add_to_coef
,
assign_coef
,
operator *
.
cp ~cs2270/.emacs .emacsNotice that the period is part of the file name. This .emacs file is the initialization file used by emacs.
-Wall
option, producing
no warnings. The one warning that is sometimes hard to get
rid of is "control reaches end of non-void function". This means that
the compile thinks that there is no return statement at the end of a
function. You can usually fix this by simplifying your code. For
example, this will produce a warning:
double polynomial::coefficient(unsigned int exponent) const { if (exponent <= MAX_EX) return coef[exponent]; else return 0.0; }But this simpler version avoids the warning:
double polynomial::coefficient(unsigned int exponent) const { if (exponent <= MAX_EX) return coef[exponent]; return 0.0; }