Fund. CS II (CS152 2005F)

Sample Solutions to Homework 2

Summary: Here you will find some sample solutions to the exercises from Homework 2.


Links to Code

Solutions To Exercises

Exercise 1: Multiplication

a. Extend the Fraction class so that it permits multiplication of two fractions.

An Answer

   * Multiply this fraction by another fraction.
  public Fraction multiply(Fraction other)
    // a/b * c/d = (a*c)/(b*d)
    return new Fraction(this.numerator.multiply(other.numerator),
  } // multiply(Fraction)

b. Test your code.

An Answer

i. Using the original fractions:

3/10 * 2/5 = 6/50

Hmmm ... perhaps I should simplify.

ii. Using fractions whose product should be 1.

1/3 * 3/1 = 3/3

iii. Using a variety of negative fractions.

-1/4 * 3/11 = -3/44
1/4 * -3/11 = -3/44
-1/4 * -3/11 = 3/44

Seems okay.

iv. Using some really big numerators and denominators

1111111111/4 * 1111111111/11 = 1234567900987654321/44
4123/1111111111 * 11/1111111111 = 45353/1234567900987654321

Still seems fine. (Yeah, I should have chosen something easier to check.)

Exercise 2: Fractional Portions

As you may know, we can represent every non-negative rational number as a whole number plus a fractional value no smaller than 0 and no bigger than 1.

a. Write a method of the Fraction class, fractional, that identifies and returns this fractional value. Your procedure need only work for positive numbers.

For example,

Fraction f = new Fraction(11,3);
   // Prints 2/3
f = new Fraction(1,2);
   // Prints 1/2
f = new Fraction(4,2);
   // Prints 0/2 or something similar

An Answer

Well, to find the fractional part, what I really want is the remainder when I divide the numerator by the denominator. I can then return the ratio of that remainder and the denominator.

A quick check of the documentation reveals that BigInteger helpfully provides a remainder(BigInteger divisor) method, so I can just use that.

   * Compute the fractional part of the fraction.  That is, if we
   * think of the fraction n/d as (a*d+b)/d, where 0 <= b < d,
   * returns d/b.
  public Fraction fractional()
    return new Fraction(numerator.remainder(this.denominator),this.denominator);
  } // fractional()

b. Test your method.

An Answer

I'll try four tests: (i) a fraction with no whole part, (ii) a fraction with no fractional part, (iii) a fraction with a small whole part, and (iv) a fraction with a large whole part.

The fractional part of 1/3 is 1/3
The fractional part of 6/3 is 0/3
The fractional part of 12/5 is 2/5
The fractional part of 1231152344523342/10 is 2/10

Exercise 3: From String to Fraction

Write and test a third constructor for the Fraction class. This constructor should accept a string as a parameter, parse that string, and generate the appropriate fraction. For example,

Fraction f = new Fraction("1/4");
   // Prints 0.25
f = new Fraction("120/3");
   // Prints 40.0

You can expect that the string will have two positive integers separated by a slash. You may find it useful to reflect on the indexOf method of the java.lang.String class and on various methods of the java.lang.Integer class.

An Answer

To convert a string of the form "num/denom" to the appropriate fields, it seems that I need to figure out two things: (i) how to separate the big string into two smaller strings (one for the numerator and one for the denominator) and (ii) how to convert each string into a BigInteger.

We've looked at the problem of separating strings in the past, so that part should be fairly straightforward. We identify the position of the separator (the slash) and take the stuff before it and the stuff after it.

The problem of converting strings to BigIntegers should only require a quick check of the documentation. Amazingly enough, although BigInteger does not provide a constructor that takes an int as a parameter, it does provide a constructor that takes a string.

Putting it all together,

   * "Parse" a string of the form "numerator/denominator" to
   * a Fraction.
  public Fraction(String description)
    // Determine the position of the slash
    int slash = description.indexOf("/");
    // Grab the numerator
    String num = description.substring(0,slash);
    // Grab the denominator
    String denom = description.substring(slash+1);
    // Convert to BigIntegers
    this.numerator = new BigInteger(num);
    this.denominator = new BigInteger(denom);
  } // Fraction(String)

We might also express this more concisely as,

  public Fraction(String description);
    // Determine the position of the slash
    int slash = description.indexOf("/");
    // Build the two fields
    this.numerator = new BigInteger(description.substring(0,slash));
    this.denominator = new BigInteger(description.substring(slash+1));
  } // Fraction(String)

Exercise 4: A Simple Calculator

Write a main class that reads in two fractions and prints out their sum and product in both fractional and decimal form.

An Answer


Exercise 5: A Counter Class

Write and test a class, Counter, that generates objects that can count. Objects in class Counter should provide two methods: increment, which adds 1 to the counter, and get, which gets the current value of the counter.

Make sure to verify that if you create two separate objects in class Counter, you can change the two objects separately.

An Answer

Counter objects will have one field, count, which is an int. increment adds one to the field. get returns the field. The one constructor will take no parameters and set the counter to 0.

See the details in

Here are some tests that suggest the two counters work independently

Initially ...
  c1 = 0, c2 = 0
After incrementing c1 ...
  c1 = 1, c2 = 0
After incrementing c2 three times ...
  c1 = 1, c2 = 3
After incrementing c1 again ...
  c1 = 2, c2 = 3

Exercise 6: Extending Counters

a. Update your Counter class to include a second constructor that Allows the user to specify a starting value.

b. Update your Counter class to include a reset method that reset the counter to the starting value.

c. Test both updates.

An Answer

Although I expected you to update, I've made a second class, which I've called

The key implementation details have to do with resetting. Since we have to reset to the starting value, we need to add a field to keep track of that value. I'll call that field start. Reset simply sets count to start.

See the details in

Here are some tests that show that we can create counters that start at 0, at a positive number, and at a negative number; that those counters increment independently; that those counters reset correctly and independently; and that increment continues to work after the reset.

Initially ...
  c1=0, c2=5, c3=-3
After incrementing c1 ...
  c1=1, c2=5, c3=-3
After incrementing c2 three times ...
  c1=1, c2=8, c3=-3
After incrementing c1 again ...
  c1=2, c2=8, c3=-3
After incrementing c3 twice ...
  c1=2, c2=8, c3=-1
After resetting c1 ...
  c1=0, c2=8, c3=-1
After incrementing c1 again ...
  c1=1, c2=8, c3=-1
After resetting c2 ...
  c1=1, c2=5, c3=-1
After incrementing c2 again ...
  c1=1, c2=6, c3=-1
After resetting c3 ...
  c1=1, c2=6, c3=-3
After incrementing c2 again ...
  c1=1, c2=6, c3=-2
After incrementing c2 again ...
  c1=1, c2=7, c3=-2



Sunday, 25 September 2005 [Samuel A. Rebelsky]

Wednesday, 28 September 2005 [Samuel A. Rebelsky]


Disclaimer: I usually create these pages on the fly, which means that I rarely proofread them and they may contain bad grammar and incorrect details. It also means that I tend to update them regularly (see the history for more details). Feel free to contact me with any suggestions for changes.

This document was generated by Siteweaver on Tue Dec 6 09:47:04 2005.
The source to the document was last modified on Wed Sep 28 10:39:48 2005.
This document may be found at

You may wish to validate this document's HTML ; Valid CSS! ; Check with Bobby

Samuel A. Rebelsky,