Posted: Jan 15th 2004
Due: Jan 29th 2004, 11:59pm (Pacific Time)
You have two weeks to complete the assignment. It's a non-trivial assignment, so you should get started early.
We'll give you the specification for this class, and the implementation for some of the member functions. You will have to decide how to represent internally the BigInt first. Then, you will complete the member (and related) functions and test it on some programs.
Summary of requirements (details appear in following sections):
Here are the operations on BigInt. You must implement them all. Do NOT change the interface of the class (otherwise we will not be able to test your code, and you will get a bad score). Assume that the big integers are always positive or zero (no sign is necessary).
class BigInt { public: BigInt(); // default constructor, value = 0 BigInt(const BigInt &); // copy constructor BigInt(int); // assign an integer value BigInt(const String &); // assign a string ~BigInt(); // destructor // operators: arithmetic, relational, output friend ostream & operator <<(ostream &, const BigInt &); const BigInt & operator += (const BigInt &); const BigInt & operator *= (const BigInt &); BigInt & operator = (const BigInt &); friend int operator == (const BigInt &, const BigInt &); friend int operator < (const BigInt &, const BigInt &); private: // add your representation here }; BigInt operator +(const BigInt &, const BigInt &); BigInt operator *(const BigInt &, const BigInt &); int operator != (const BigInt &, const BigInt &); int operator > (const BigInt &, const BigInt &); int operator >= (const BigInt &, const BigInt &); int operator <= (const BigInt &, const BigInt &);
Multiplication is a special case. There is an implementation of *= in the current BigInt.cc, implemented in terms of += (i.e., using repeated additions). You may use this version of the function to help you test your += function, although won't be able to use it until you've implemented several of the other functions too. However, you are required to reimplement *= in a more efficient way for your final program (see Hints on Arithmetic Operations, below).
See BigInt.h for more thorough specification of these functions.
The internal representation is your choice, as long as it is dynamically allocated (i.e., dynamic array, STL vectors, strings, etc.).
Hints on arithmetic operations
Make sure that you grow your array/vector/string enough to store the result.
You are required to add and multiply using the grade school methods you learned. For add that means adding digit by digit, and carrying a 1 where necessary. When working on your algorithm for a+=b we recommend you consider cases where a has more digits, b has more digits, and they are the same size.
To multiply a BigInt by a BigInt consider the example below:
1 | 2 | 3 | 4 | 5 | 6 | |||
x | 7 | 8 | 9 | |||||
---------------------------------- | ||||||||
1 | 1 | 1 | 1 | 1 | 0 | 4 | ||
9 | 8 | 7 | 6 | 4 | 8 | 0 | ||
8 | 6 | 4 | 1 | 9 | 2 | 0 | 0 | |
---------------------------------- | ||||||||
9 | 7 | 4 | 0 | 6 | 7 | 8 | 4 |
Note that each partial product is shifted-left (padded with the appropriate number of zeros). Rather than shift the partial product by adding the appropriate number of zeros, one of the numbers being multiplied can be shifted (of course this is what is really happening in the example above where the top number is multiplied by 9, 80, and 700). This allows the product to be accumulated by summing a sequence of partial products where each partial product involves multiplying by a digit in the range 0-9. In the example above the final product is computed by
(123,456 X 9) + (1,234,560 X 8) + (12,345,600 X 7)Note that each partial product involves the product of a BigInt and a digit in the range 0-9. Thus the partial products can be computed using a private auxiliary member function which multiplies its implicit parameter by a single digit. The prototype for this member function might be void BigInt::multByDigit(int digit)
Once you implement < and ==, the other relational operators are
already defined in terms of those two.
Testing your code
You are responsible for writing a test program, called
bigtest.cc, that will thoroughly test all of your member
functions; bigtest.cc will be compiled separately from your BigInt
code. You are also required to add the necessary rules to the
Makefile so that make bigtest will create the executable.
You may structure your test program in a few possible ways: one option is a program that takes no input, and runs several fixed tests over BigInts created in the program. Your output should be somewhat self-explanatory. E.g., for one of the tests of your add function, you could print the value of the BigInts being added (before the add), and what the result was, e.g.:
30 + 4 = 70(and with the output shown we could easily see that there is a bug in the BigInt class being tested!).
Or your program could take some input for BigInt values (i.e., they would be read in as Strings), to make it easier to test the same operations on different values. If your program takes input, you are also required to provide test data files for the program which collectively completely test your program. Your program should just read from cin, and you can use UNIX input redirection to get the input from a file.
How thoroughly you test your BigInt code will be a non-trivial portion of your grade on this assignment.
We have given you a Makefile which makes an executable fact from fact.cc when you type make. You need to add rules to this Makefile for compiling your test program.
The program prompts for a number and then prints factorials from the entered number down to 1. If you invoke the program with a command-line argument as in fact 14 it will compute and print all factorials from the command-line argument down to 1.
For you convience, we are providing the executable for fact. You can use our executable to check the correctness of your program. Download the executable for Linux/i386 here (right-click, "Save Link As...", and then change the permission to executable)
For example, if your code to build a BigInt is untested, and you are testing += at the same time, it's difficult to determine where to look for any bugs that appear when you try to add. If, instead, you already know that your BigInts are being built correctly (because you tested this code in isolation), then you can isolate mistakes to +=.
A minimal subset you might want to test initially is one or more of your BigInt constructors with the printing routine (already written for you). Once you get your copy constructor, assignment operator and destructor working, you can then tackle the relational operators and +=, testing the latter in part using the *= operator (which is currently implemented in terms of +=). Then you can reimplement *=.
description | points |
---|---|
program compiles with no errors/warnings | 10 points |
constructors/destructors/output operator work | 10 points |
comparison operators work | 5 points |
operator + works | 15 points |
re-implemented operator * works | 20 points |
robustness (i.e., program survives nasty cases) | 20 points |
program style (program design, comments, README) | 20 points |