Computer Science 3675
Fall 2001
Programming Assignment 1

Due: September 6, 11:59pm

Arithmetic on large integers can be done by storing an integer in an array, in binary notation. So each member of the array holds either 0 or 1. Functions can be written to perform operations such as addition, subtraction, multiplication and division.


Functions

Write an implementation of increment, decrement, addition subtraction stored in binary, in C++. Make your functions have the following contracts and prototypes.

  //  -----------------------------------------------------------
  // |The following comments apply to all of the functions below.|
  //  -----------------------------------------------------------
  //
  // All integers are stored in binary as arrays of bits, with the least
  // significant bit stored at index 0.
  //
  // Array A has m bits.
  // Array B has n bits.
  //
  // It is the caller's responsibility to ensure that array R 
  // has enough cells available to hold the answer.  The number
  // required is given for each function.  
  //
  // Variable k is set to hold the number of bits that are actually
  // in array R, not counting leading 0 bits.  For example, if
  // R contains 0110, then its length is 3, since the leading 0
  // is ignored.  If R contains 0, then the length is 0.
  //  
  // It is allowed for arrays R and A to be the same array, or
  // for R to be a different array.  When R and A are the same
  // array, the result is put into array A,
  // clobbering the former contents of A.

  //=================================================================
  //
  // inc(R,k,A,m) stores one larger than the binary number in A into
  // array R.  That is, it computes R = A + 1 in binary.
  // It sets k to the number of bits in array R.
  //
  // Array R must have at least m+1 cells available.

  void inc(BIT R[], int& k, const BIT A[], int m);

  //=================================================================
  //
  // dec(R,k,A,m) stores one less than the binary number in A into
  // array R.  That is, it computes R = A - 1 in binary.
  // If A holds 0, then R is set to hold 0 as well.
  // Variable k is set to hold the number of bits in array R.
  //
  // Array R must have at least m cells available.

  void dec(BIT R[], int& k, const BIT A[], int m);

  //=================================================================
  //
  // sum(R,k,A,m,B,n) stores the sum of integers A and B 
  // into array R.  That is, it computes R = A + B.
  // It stores the number of bits of R into variable k.
  //
  // Array R must have at least max(m,n) + 1 cells available.

  void sum(BIT R[], int& k, const BIT A[], int m, const BIT B[], int n);

  //=================================================================
  //
  // diff(R,k,A,m,B,n) stores the difference of integers A and B 
  // into array R.  That is, it computes R = A - B.  If A < B, then
  // it sets R = 0.  It stores the number of bits of R into variable
  // k.
  //
  // Array R must have at least max(m,n) cells available.

  void diff(BIT R[], int& k, const BIT A[], int m, const BIT B[], int n);
For type BIT, use int. So you should write
  typedef int BIT;
in a header file for your functions. Do not put this typedef in the implementation file that you turn in.


Requirements

You are not asked to write a complete application here. Only the functions listed are to be provided. They are for use in other programs. I will test them by using them in another program.

For ease of grading, call your implementation file arithmetic.cc and your header file arithmetic.h. Do not include a main function in arithmetic.cc.

Your functions should meet the following requirements. (And yes, I will grade down for failure to meet these requirements, even if you have not been asked to meet such stringent requirements in the past.)

  1. Your functions must have exactly the prototypes shown. If they do not, they will not link with my tester.

  2. Your functions must not make any assumptions about how large the arrays are, other than those explicitly stated in the contracts. For example, it is unacceptable to assume that the numbers have no more than 100 bits in them. It must be possible to compile your functions and put them into a library, and find that they can be used for arbitrarily large integers without recompiling them.

  3. Your functions must not have requirements that are not stated in the contracts. For example, it is unacceptable to insist that array C be set to all zeros by the caller before calling sum since the contract does not say anything about that.

  4. Your functions must not have any visible actions not stated in the contracts. For example, the contracts do not indicate that anything is being read or written, so nothing should be read or written. (Don't use cin or cout, for example.)

  5. Your functions must implement something close to the standard increment, decrement, addition and subtraction algorithms. It is not acceptable, for example, to add x and y by starting at x and doing y increments. That is extremely slow.

  6. Strive for simplicity and elegance in your program. This is important, since you will be comparing your solution in C++ to another form of solution.

  7. Comment your program well. Make it clear and readable. Literate programming is a form of programming where programs are written in a way that is intended to be read, as a textbook would be read. Get as close to literate programming as you can. Write your program for other people to read.

If you feel that these requirements are impossible to meet, or you do not see how to meet them, ask for help.


Testing the functions

Test your functions. In order to do the testing, you will want a function that prints a binary number. That is not part of the assignment, and should not be turned in, but software designers often find that they need to write extra functions to aid in testing.

IF YOU DO NOT TEST YOUR FUNCTIONS, YOU CAN REST ASSURED THAT THEY DO NOT WORK, AND THEY WILL FARE POORLY WHEN GRADED.

Here are some recommended tests. You would be well advised to do others as well. All numbers are in standard binary notation (high order bit first).

  1. 0 + 0 = 0
  2. 1 + 1 = 10
  3. 10 + 11 = 101
  4. 101001 + 101111100 = 110100101
  5. 101111100 + 101001 = 110100101
  6. 111111 + 111111111111 = 1000000111110
  7. 111111111111 + 111111 = 1000000111110
  8. 1111111111111111111111111111111111111111 + 1 = 10000000000000000000000000000000000000000
  9. 0 - 0 = 0
  10. 0 - 1 = 0
  11. 1 - 0 = 1
  12. 11 - 10 = 1
  13. 11 - 0 = 11
  14. 11 - 1 = 10
  15. 101111100 - 101001 = 101010011
  16. 10000000000000000000000000000000000000000 - 1 = 1111111111111111111111111111111111111111

An easy way to do these tests is just to initialize some arrays in your program. For example, write

    BIT A3[] = {1,0,0,1,0,1};
    BIT B3[] = {0,0,1,1,1,1,1,0,1};
to initialize arrays A3 and B3 to the binary numbers 101001 and 101111100, respectively. Notice that the numbers are written in the arrays with the least significant bit first. I have written the examples with the most significant bit first.


How to turn in the assignment

Turn in your program using the handin program. Do that as follows.

  1. In your .cshrc file, put the following line, using a text editor.

         alias handin3675 "/export/stu/classes/csci3675/bin/handin csci3675"
    Be sure that any terminal window that you use is started after you make this change to the .cshrc file.

  2. To hand in file arithmetic.cc, use the following command (in a terminal window).

        handin3675 1 arithmetic.cc

  3. Check the response. You should get an indication that the file was handed in successfully. If you do not, the handin was not successful. Check that your alias line in the .cshrc file is correct, and that your file exists in the current directory. If handin says the assignment does not exist, or that you are not a student in the class, then there is a problem with the configuration files for handin. Send me email telling me what the problem is.