CIT 591 Assignment 6: Fractions and Complex Numbers Fall 2004, David Matuszek

Purposes of this assignment:

• To teach you to use JUnit.
• To give you some practice in writing APIs.

General idea of the assignment:

Implement (1) fractions and (2) complex numbers, as an API. Write very thorough JUnit tests.

Details:

Java provides several types of numbers, but it does not provide fractions or complex numbers. Your task is to implement one of these, and provide tests for the other.

The following table lists the kind of data and the kind of operations you will need.

Fraction Complex numbers
Components Two integers, known as the numerator and the denominator. Two doubles, known as the real part and the imaginary part.
How written `n/d`, where `n` is the numerator and `d` is the denominator `a+bi` (or` a-bi`, if `b` is negative), where `a` is the real part and `b` is the imaginary part; the "i" is a symbol denoting "imaginary"
Restrictions The denominator may not be zero None
Normalization The fraction is always kept in the lowest terms, that is, the Greatest Common Divisor (GCD) of `n` and `d` is` 1` (use Euclid's algorithm); and
The denominator is never negative
None, really. However, if the imaginary part is negative, it is written as `a-bi` rather than `a+-bi`.
Addition `a/b + c/d` is `(ad + bc)/bd` `a+bi + c+di` is `(a+c)+(b+d)i`
Subtraction `a/b - c/d` is `(ad - bc)/bd` `a+bi - c+di` is `(a-c)+(b-d)i`
Multiplication `(a/b) * (c/d) `is `(a*c)/(b*d)` `(a+bi) * (c+di)` is `(ac-bd)+(ad+bc)i`
Division `(a/b) / (c/d)` is` (a*d)/(b*c)`

`(a+bi) / (c+di)` is ```(ac+bd)/(c2+d2) + (bc-ad)/(c2+d2)i```

Absolute Value Assuming that `a/b` is normalized:
`a > 0 ? a / b : -a / b`
`sqrt(a2+b2`) (Same as distance from `0+0i`)
Negation `-(a/b)` is `-a/b` `-(a+bi)` is `-a-bi`
Special Inverse of `a/b` is `b/a` Complex conjugate of `a+bi` is `a-bi`
Equality If in lowest terms, numerators are equal and denominators are equal Equality of floating point numbers is not well defined--but you can test if two numbers are approximately equal
Greater Than `a/b > c/d` if `ad > bc` Can be defined as having the greater distance from `0+0i`
Less Than `a/b < c/d` if `c/d > a/b` Can be defined as having the lesser distance from `0+0i`
Distance Not applicable Distance between `a+bi` and `c+di` is `sqrt((a-c)2+(b-d)2)+0i`
Zero Zero is `0/1` Zero is `0+0i`

 The `Fraction` class should have three constructors: One that takes two `int` parameters, a numerator and a denominator One that takes one `int` parameter, the numerator (the denominator is assumed to be one) A `String` such as `"5/10"`, or `"2"` (allow blanks in the string) And these `public` methods: `public Fraction add(Fraction f)` `public Fraction subtract(Fraction f)` `public Fraction multiply(Fraction f)` `public Fraction divide(Fraction f)` `public Fraction abs()` `public Fraction negate()` `public Fraction inverse()` `public boolean equals(Object o)` `public boolean greaterThan(Fraction f)` `public boolean lessThan(Fraction f)` `public String toString()` Fractions should always be kept in a normalized form; normalization should therefore be done by a `private` method. The `Complex` class should have three constructors: One that takes two `double` parameters, a real part and an imaginary part One that takes one `double` parameter, the real part (the imaginary part is assumed to be zero) A `String` such as `"3+5i"`, or `"17.5-21.3i"`, or `"3.1416"`, or `"99i"` (allow blanks in the string) And these `public` methods: `public Complex add(Complex c)` `public Complex subtract(Complex c)` `public Complex multiply(Complex c)` `public Complex divide(Complex c)` ```public double abs() // changed return type``` `public Complex negate()` `public Complex conjugate()` `public double distance(Complex c) // added` `public boolean approximatelyEquals(Complex c)` `public boolean greaterThan(Complex c)` `public boolean lessThan(Complex c)` `public String toString()`

All numbers should be immutable, that is, there should be no way to change their components after the numbers have been created. Most of your methods simply return a new number.

When you override `equals` from the Object class, notice that it requires an `Object` as a parameter. This means that the first thing the method should do is make sure that its parameter is in fact a `Fraction`, and return `false` if it is not.

To determine whether two complex numbers are approximately equal: Notice that, in some sense, `1234500` and `1234600` are "more equal" than `0.5` and `2.0`, because the percentage difference is much greater in the second case. We will therefore define two complex numbers to be "approximately equal" if the distance between them is less than one millionth of the distance of the larger number from zero (`0+0i`). Change: To simplify testing, you can define "approximately equal" to mean that the distance between two Complex numbers is less that `0.001`. This allows you to use the JUnit method ```assertEquals(expected, actual, 0.001)```, where `expected` and `actual` are doubles.

To put a fraction into its lowest terms, divide both the numerator and the denominator by their Greatest Common Divisor (GCD). Euclid's algorithm finds the GCD of two integers. It works as follows: As long as the two numbers are not equal, replace the larger number with the remainder of dividing the larger by the smaller (that is, `larger = larger % smaller`). When the two numbers are equal, that value is the GCD. (If this brief explanation isn't enough, look up Euclid's algorithm on the Web.)

You will do this assignment with a partner. One of you should write the `Fraction` class and the JUnit test for the `Complex` class; the other should write the `Complex` class and the JUnit test for the `Fraction` class. In other words, you each write tests for each other. In a way, this is a sort of competition; you are trying to find more bugs in your partner's class than he/she can find in yours. The desired end result is, of course, that both of you end up bug-free.

For this assignment, you must have a partner. Partners will be assigned as usual, and if for some reason you end up without a partner, it is your responsibility to find one. You can have more than one partner--notice that extra partners will not increase your work load (you still write the same amount of code). If you already have a partner and someone else (doing the opposite kind of number) needs a partner, please oblige if you can.

Every class you write should mention (in the Javadoc comments) that you are the author. In addition, your number class should indicate whose JUnit tests you used, and your JUnit class should indicate who used your tests.

Your goal in writing the number class should be to deal correctly with all possible cases. Throw `Exception`s where appropriate--look at the various `Exception` classes, and use the same kinds of `Exception`s as you might get when dealing with `int`s or `double`s. (If you aren't sure what kinds of `Exception`s are appropriate, don't ask me about it--experiment with operations on Java's numeric types to see what they do.)

Your goal in writing the JUnit class is to test for every possible error. This includes making sure that the correct `Exception`s are thrown when appropriate.