CS 211
Project 3
due April 7, 2010

The program

Your program will be a calculator which does arithmetic on fractions. User input can be either in the form of proper fractions (e.g. 2 1/3) or improper fractions (e.g. 7/3). In which form output is displayed is an option for the user.

The calculator will have an accumulator which holds a fraction which is displayed at all times. It is initially 0. The user can perform any of the operations which appear in the menu below. The accumulator is always an argument. When a second argument is needed (for add, subtract, multiply, divide) the program will prompt the user to provide a number. Running the program may give:


0

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  a
   >  -26/8

-3 1/4

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  i

-13/4

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  p

-3 1/4

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  r

-4/13

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  m
   >  2 7/2

-1 9/13

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  r

-13/22

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  n

13/22

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  s
   >  8

-7 9/22

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  d
   >  3/2

-4 31/33

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  c

0

add:         a,  clear:            c
subtract:    s,  reverse sign:     n
multiply:    m,  proper display:   p
divide:      d,  improper display: i
reciprocal:  r,  quit:             q
->  q
??

Files and classes

Your program will be written in two files: one, Fraction.java, will define a fraction class. Instances will fractions and a number of operations will be provided. The other file will have a class with the main and any other methods you need to run the calculator (all fields and methods in this class must be declared static).

The Fraction class

This class will have two int fields: numerator and denominator. There will be a constructor which takes two int parameters and uses them to initialize the fields and a second constructor taking no parameters which intializes the fraction to 0 (numerator gets 0 and denominator gets 1). There will also be "get" and "set" methods for the fields.

If the fraction is to be negative numerator will be negative (denominator will always have a positive value). If an attempt is made to construct a fraction with 0 denominator an "attempt to divide by 0" messeage will be displayed and the program will terminate (use System.exit(1)).

The fraction will always be kept reduced to lowest terms. This is done by dividing the numerator and denominator by their greated common divisor (GCD). GCD can be computed using Euclid's algorithm:


GCD (a, b)
{
   // a and b are both positive
   let max = max(a, b)
   let min = min(a, b)
   do
      remainder = max % min
      if (remainder ≠ 0)
         max = min
         min = remainder
   while (remainder ≠ 0)
   min is the GCD
}

There will be public methods for the operations: add, subtract, multiply, divide, reciprocal, and reverse sign. Each of these will operate on "this", i.e. the current instance of the class. Operations which take two arguments (add, subtract, multiply, and divide) will use this as the first and a parameter as the second. For example, to add an instance fr of Fraction to the current instance of Fraction you will write a method add(Fraction fr) which will return the new Fraction value which is the sum of this and fr. Fraction arithmetic is just as you learned in elementary school.

You will provide a toString() method (no parameters) which returns a String representation of the fraction. The representation returned will be an improper fraction, that is it will be numerator/denominator (with a possible minus sign) even if the numerator is larger than the denominator. This will allow you to get output by simply passing a Fraction to System.out.print() (the value returned from toString() will be displayed). You will also write a method public String proper() which will return the String representation of the proper fraction (e.g. 3 1/3 rather than 10/3) if the numerator is greater than the denominator and a simple fraction if the numerator is smaller than the denominator. For both of these methods an integer will be represented if the denominator is 1 (e.g. "-77" rather than "-77/1"). These two methods will require care to write properly. These methods will use the Integer.toString() method. (Note that Integer.toString() is a static method but your toString() method will not be.)

You will also need a (static) parseFraction(String s) which will return an instance of Fraction which is represented by the String s. You can use the (rather ugly) method here. This method returns null if s doesn't represent a valid fraction. This method will convert Strings which are either proper or improper fractions.

The calculator

The workings of the calculator are described above. Initially the accumulator (holding the current calculator value) will have the value 0. Arithmetic operations (add, subtract, multiply, divide) will use the accumulator as the first argument and get the second argument from the user and leave the result as the new value of the accumulator. Clear will reset the accumulator to 0. Reciprocal and reverse sign will modify the accumulator. "Proper display" will cause the output to appear as proper fractions (e.g. 1 3/10) if the numerator is larger than the denominator and "improper display" will cause the output appear as a single fraction (e.g. 13/10). The calculator will start with proper display.

All input will be read with kbd.nextLine() and converted to a Fraction with Fraction.parseFraction() If the user's input is invalid (Fraction.parseFraction() returns null) an error message is displayed and no operation is performed. The accumulator remains unchanged. If the user tries to take the reciprocal of 0 or tries to divide by zero an error message is displayed and the program will be terminated. (Division by zero errors can be handled from the constructor for Fraction and the setDenominator method -- don't allow denominator to be 0.)

To turn in

You will turn in your source code electronically through your lab section's blackboard.

html>