- Forward


Compound Numbers
A Programming Pattern


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

Motivation
Back SMYC Forward
  • What is a Compound Number?
    • A compound number is a quantity/measure that is expressed in more than one unit
  • Examples:
    • Heights/lengths measured in miles, yards, feet and inches
    • Weights measured in tons, pounds and ounces
    • Times measured in hours, minutes and seconds
    • Volumes measured in gallons, quarts, pints, ounces
Two Observations
Back SMYC Forward
  • Individual Components:
    • Are commonly integers (because parts of a whole are usually denominated in different units)
  • Arithmetic Operations:
    • Often involve arithmetic on a circle with "carry"
The Obvious Implementation
Back SMYC Forward
  • The Approach:
    • Have an attribute for each of the individual units (e.g., an int for pounds and an int for ounces)
  • Why it Seems Clever:
    • Because we know about the integer division and remainder operators and how to use them for arithmetic on a circle and divisibility checks
  • A Continuing Example:
    • We have 3lbs,12oz of french fries and someone gives us more or takes some away
The Continuing Example
Back SMYC Forward
  • An Example of the Easiest Case:
    • We have 3lbs,12oz of french fries and someone gives us 2oz more
  • Processing this Specific Example:
    • ounces = ounces + 2;
  • Processing this Kind of Example:
    • ounces = ounces + deltaounces;
The Continuing Example (cont.)
Back SMYC Forward
  • An More Difficult Example:
    • We have 3lbs,12oz of french fries and someone gives us 8oz more
  • Processing:
    • pounds = pounds + (ounces + deltaounces) / 16;
      ounces = (ounces + deltaounces) % 16;
  • A Word of Caution:
    • The following code, while similar, is incorrect!
      ounces = (ounces + deltaounces) % 16;
      pounds = pounds + (ounces + deltaounces) / 16;
The Continuing Example (cont.)
Back SMYC Forward
  • Increasing the Difficulty Further:
    • We have 3lbs,12oz of french fries and someone gives us 5lbs,8oz more
  • Processing:
    • pounds = (pounds + deltapounds) + (ounces + deltaounces) / 16;
      ounces = (ounces + deltaounces) % 16;
The Continuing Example (cont.)
Back SMYC Forward
  • Increasing the Difficulty Further:
    • We have 1ton,1999lbs,12oz of french fries and someone gives us 8oz more
  • Processing:
    • tons = (tons + deltatons) + (pounds + deltapounds + (ounces + deltaounces) / 16) / 2000;
      pounds = (pounds + deltapounds) + (ounces + deltaounces) / 16;
      ounces = (ounces + deltaounces) % 16;
The Continuing Example (cont.)
Back SMYC Forward
  • Increasing the Difficulty Further:
    • We have 1ton,1999lbs,12oz of french fries and someone gives us 1ton,200lbs,8oz more
  • Increasing the Difficulty Further:
    • We have 2tons,1999lbs,12oz of french fries and someone changes the amount by -1ton,353lbs,-15oz
  • Other Complications:
    • Multiplication/division by a constant
    • Ratios
    • Sign (should all components have the same sign?)
    • Comparisons (e.g., equals(), compareTo())
Learning from these Examples
Back SMYC Forward
  • A Conclusion:
    • It is possible to use the obvious implementation but there are many ways/places that defects can be introduced
  • A Hope:
    • This situation has arisen frequently in the past and people have developed a solution
A Better Implementation
Back SMYC Forward
  • The Idea:
    • Use a single attribute denominated in the "smallest" units and convert when necessary
  • The Continuing Example Revisited:
    • Create a Weight class that has only one attribute measured in ounces, but accessors that can return tons, pounds and ounces and mutators that can be passed tons, pounds, and ounces
A Better Implementation (cont.)
Back SMYC Forward
javaexamples/compoundnumbers/Weight.java
 
Don't Be Confused!
Back SMYC Forward
  • A Common Misconception:
    • The shortcomings of the obvious implementation arise only if the objects are mutable
  • The Reality:
    • The shortcomings exist whenever operations are performed on compound numbers (regardless of whether the object is mutable or a new immutable object is created)
There's Always More to Learn
Back -