// Money Money (copyright 1996, Information Disciplines, Inc) public class Money { // Internal representation: Always an integer, scaled so that unity // ----------------------- is the smallest measurable quantity public static short scale=100;// Smallest fraction of monetary unit to // be represented (e.g. 100: cents, // 200: 8ths, 1000: mills); // User can override before creating // any Money objects protected long value; // Amount in monetary units * scale // Constructors and assignment operations // -------------------------------------- // To support literal constants as well as simple input, we allow // conversion from floating point, just as in the constructor. public Money(final double x) {value = Math.round(x * scale);} public Money() {} // Default constructor, for efficiency public Money(final Money x) {value = x.value;} // Pseudo assignment operators // --------------------------- public Money set(final Money rs) {value= rs.value; return this;} public Money set(final double rs) {value= Math.round(rs * scale); return this;} // Accessors // --------- public long wholeUnits() {return value / scale;} public short cents () {return (short)((value*100)/scale - (100 * wholeUnits()));} // Numeric utility functions // ------------------------- public Money abs() {Money result = new Money(this); if (value < 0) result.value = - result.value; return result; } public short sign() {return (short)(value > 0 ? 1 : value < 0 ? -1 : 0);} // Relational (predicate) operations: // --------------------------------- public boolean equals (final Money rs) {return value == rs.value;} public boolean lessThan (final Money rs) {return value < rs.value;} public boolean greaterThan (final Money rs) {return value > rs.value;} public boolean equals (final double rs) {return value == rs * scale;} public boolean lessThan (final double rs) {return value < rs * scale;} public boolean greaterThan (final double rs) {return value > rs * scale;} // These three functions are to comply with Java library conventions. // They are rarely needed in manipulating Money objects. public boolean equals (final Object rs) {return rs instanceof Money && ((Money)rs).value == value;} public int compareTo (final Object rs) {return sub((Money)rs).sign();} public int hashCode () {return (new Long(value)).hashCode();} // Arithmetic operations: // --------------------- public: Money addSet(Money rs) {value += rs.value; return this;} public: Money addSet(long rs) {value += rs * scale; return this;} public: Money subSet(Money rs) {value -= rs.value; return this;} public: Money subSet(long rs) {value -= rs * scale; return this;} public: Money mpySet(long rs) {value *= rs; return this;} public: Money divSet(long rs) {value /= rs; return this;} public: Money modSet(Money rs) {value %= rs; return this;} public: Money modSet(long rs) { return this;} public: double div(Money rs) {return ;} public: Money minus() {return ;} // Completely defined functions -- no fill-in needed: // ---------------------------- public: Money add(Money rs) {return new Money(this).addSet(rs);} public: Money sub(Money rs) {return new Money(this).subSet(rs);} public: Money mpy(double rs) {return new Money(this).mpySet(rs);} public: Money div(double rs) {return new Money(this).divSet(rs);} public: Money mod(Money rs) {return new Money(this).modSet(rs);} public: Money mod(double rs) {return new Money(this).modSet(rs);} public Money addSet (final Money rs) {value += rs.value; return this;} public Money addSet (final double rs) {value += rs * scale; return this;} public Money subSet (final Money rs) {value -= rs.value; return this;} public Money subSet (final double rs) {value -= rs * scale; return this;} public Money mpySet (final double rs) {value *= rs; return this;} public Money divSet (final double rs) {Math.round(value/=rs); return this;} public Money minusSet() {value = - value; return this;} public Money add (final Money rs) {return new Money(this).addSet(rs);} public Money add (final double rs) {return new Money(this).addSet(rs);} public Money sub (final Money rs) {return new Money(this).subSet(rs);} public Money sub (final double rs) {return new Money(this).subSet(rs);} public Money mpy (final double rs) {return new Money(this).mpySet(rs);} public Money div (final double rs) {return new Money(this).divSet(rs);} public double div (final Money rs) {return Math.round(value/rs.value);} public Money minus() {return new Money(this).minusSet();} //%EJECT // External representation: Constants used in output and input functions // ----------------------- (User may override) public static String pfx_symbol = "$"; // Leading currency symbol public static String sfx_symbol = ""; // Trailing currency symbol public static char decimal_point = '.'; // Character for fractions public static char group_separator = ','; // Character for 1000nds public static String unit_name = "dollar"; // Name of monetary unit public static String cent_name = "cent"; // Name of fraction unit //%SPACE 3 // Conversion functions // -------------------- // The following function is needed by toString (below) in order to // develop its result in left-to-right order: private static short log10(long x) // This function returns the number {short result; // of decimal digits in an integer for (result=0; x>=10; result++, x/=10); // Decimal "shift" and count return result; } //%SPACE 2 // Conversion to string // -------------------- // The result (external Money representation) is the concatenation of: // - a leading minus sign, if needed // - the prefix currency symbol, if any (U.S.: '$') // - groups of 3-digits separated by the group_separator (English: comma) // (no leading zeros on the leftmost group) // - a decimal point (English: period) // - the fractional portion, normally two digits, more if needed // and if scale > 100 // - the suffix currency symbol, if any (U.S.: none) public String toString () {boolean negative = (value < 0); // Remember original sign value = negative ? -value : value; // Discard sign temporarily long whole = wholeUnits(); // Separate arg. into whole short cents = cents(); // and fractional monetary units short rest = (short)(value - (cents + 100 * whole) * scale / 100); String result = (negative ? "-" : ""); // Insert prefix minus, if needed result = result + pfx_symbol; // Insert dollar sign or equiv. // (function continued on next page) //%EJECT // Append groups of 3 digits separated by punctuation long divisors[] = { 1, 1000, 1000000, (long)1E9, (long)1E12,(long)1E15, (long)1E18}; int group_no = log10(whole) / 3; int group_val = (int)(whole / divisors[group_no]); result = result + group_val; // Append leftmost 3-digits // without leading 0's while (group_no > 0) // For each remaining 3-digit group {result = result + group_separator; // Insert punctuation whole -= group_val * divisors[group_no--]; // Compute new remainder group_val = (short)(whole/divisors[group_no]);// Get next 3-digit value if (group_val < 100) result = result + "0"; // Insert embedded 0's if (group_val < 10) result = result + "0"; // as needed result = result + group_val; // Append group value } // Append the fractional portion result = result + decimal_point; // Append decimal point if (cents < 10) // Insert leading 0 if needed result = result + "0"; result = result + cents; // Append cents value if (rest > 0) // Test for fractional pennies {while ((rest *= 10) < scale); // (rest *= power(10,log10(scale))) result = result + (rest/scale);// Append fractional pennies, if any } if (negative) value = - value; // Restore original sign return result + sfx_symbol; // Append final symbol, if any } // ******* End of toString function } // ******* End of class definition