JMU
Compound Numbers
A Programming Pattern


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Motivation
Two Observations
The Obvious Implementation
The Continuing Example
The Continuing Example (cont.)
The Continuing Example (cont.)
The Continuing Example (cont.)
The Continuing Example (cont.)
Learning from these Examples
A Better Implementation
A Better Implementation (cont.)
javaexamples/compoundnumbers/Weight.java
        import java.util.*;


/**
 * A weight class that uses the compound number programming pattern.
 *
 * Note: This class also uses: information hiding, static attributes,
 * overloaded methods, and overloaded constructors.
 *
 * @author  Prof. David Bernstein, James Madison University
 */
public class Weight
{
    private static final int OUNCES_PER_POUND =   16;
    private static final int POUNDS_PER_TON   = 2000;
    private static final int OUNCES_PER_TON   = OUNCES_PER_POUND*POUNDS_PER_TON;
    

    private int      value;

    /**
     * Construct a Weight of 0.
     */
    public Weight()
    {
        value = 0;
    }

    /**
     * Construct a Weight.
     * Note: The signs of the parameters do not have to agree.
     *
     * @param tons       The number of tons
     * @param pounds     The number of pounds
     * @param ounces     The number of ounces
     */
    public Weight(int tons, int pounds, int ounces)
    {
        value = 0;
        changeBy(tons, pounds, ounces);
    }

    /**
     * Change this Weight by a given amount.
     * Note: The signs of the parameters do not have to agree.
     *
     * @param tons       The number of tons
     * @param pounds     The number of pounds
     * @param ounces     The number of ounces
     */
    public void changeBy(int tons, int pounds, int ounces)
    {
        value += tons * OUNCES_PER_TON + pounds * OUNCES_PER_POUND + ounces;
    }

    /**
     * Change this Weight by a given amount.
     *
     * @param other      The Weight to change by
     */
    public void changeBy(Weight other)
    {
        value += other.value;
    }

    /**
     * Check to see if this Weight is equal to 
     * a given Weight.
     *
     * @param other   The other Weight to use in the comparison
     * @return        true if the two are equal and false otherwise
     */
    public boolean equals(Weight other)
    {
        return this.value == other.value;
    }

    /**
     * Multiply this Weight by a scalar.
     * Note: This method truncates the ounces if necessary.
     *
     * @param m   The scalar multiple
     */
    public void multiplyBy(double m)
    {
        value = (int)(value * m);
    }
    
    /**
     * Get a String representation of this Weight.
     *
     * @return  The String
     */ 
    public String toString()
    {
        int        ounces, pounds, tons, unsigned;
        String     s;
        
        unsigned = Math.abs(value);        
        tons   = (unsigned / OUNCES_PER_TON);
        pounds = (unsigned % OUNCES_PER_TON) / OUNCES_PER_POUND;
        ounces = (unsigned % OUNCES_PER_TON) % OUNCES_PER_POUND;

        s = new String();
        if (value < 0) s += "Negative";

        if      (tons > 1) s += " " + tons + "tons";
        else if (tons > 0) s += " " + tons + "ton";
        
        if      (pounds > 1) s += " " + pounds + "pounds";
        else if (pounds > 0) s += " " + pounds + "pound";

        if      (ounces > 1) s += " " + ounces + "ounces";
        else                 s += " " + ounces + "ounce";
        
        return s;
    }
}
        
Don't Be Confused!