//%TITLE IDI money class: implementation of non-in-line functions // Copyright 1995, Information Disciplines, Inc., Chicago // See MONEY.H for documentation and declarations //%SPACE 3 #include #include "money.h" //%SPACE 3 // Initial (default) constant values // --------------------------------- char money::pfx_symbol[] = "$"; char money::sfx_symbol[] = "" ; char money::decimal_point = '.'; char money::group_separator = ','; char money::unit_name[] = "dollar"; char money::cent_name[] = "cent"; moneyIType money::scale = 100; // For cents - use 200 for eighths //%SPACE 4 double money::round(const double x) // Static internal function {double dummy; return modf(x + (x<0 ? -.5 : .5),&dummy), dummy; // to round and truncate } //%EJECT // Output display (stream insertion) operator // ------------------------------------------ // This version displays a money object in the form: // - leading minus sign, if negative // - floating prefix currency symbol (if symbol_pfx = 1) // - whole amount in groups of three digits separated by punctuation // - decimal point // - 2-digit (or more when needed) decimal fraction ostream& operator<< (ostream& ls, MONEY rs) {money absx = rs > 0 ? rs : - rs; // Get magnitude of argument double whole = absx.moneyInt(); // Isolate whole monetary units short cents = absx.moneyCents(); // Isolate fractional units money remdr = absx - money((whole * 100 + cents) / 100); if (rs < 0) ls << '-'; // Print prefix minus, if needed ls << money::pfx_symbol; // Insert dollar sign // Print groups of 3 digits separated by punctuation // ------------------------------------------------- const double group_divisors[6] = {1E0, 1E3, 1E6, 1E9, 1E12, 1E15}; short group_no = (whole == 0) ? 0 : short( log10(whole) / 3 ); int group = int( whole / group_divisors[group_no] ); ls << group; // Print leftmost 3-digits (no leading 0's) while (group_no) // For remaining 3-digit groups {ls << rs.group_separator; // Print group separator whole -= group * group_divisors[group_no--]; // Compute new remainder group = int( whole / group_divisors[group_no] ); // Get next 3-digit value if (group < 100) ls << '0'; // Insert embedded 0's if (group < 10) ls << '0'; // as needed ls << group;} // Print 3-digit value // Print cents portion // ------------------- ls << rs.decimal_point // Append decimal point << (cents < 10 ? "0" : "") // Append leading 0 if needed << cents; // Append cents value // Append any additional fractional digits // --------------------------------------- for (int i = int( money::scale/100 -1 ); i&&(remdr>0); i--, remdr/=10) ls << (10 * remdr).moneyCents(); ls << money::sfx_symbol; // Insert trailing currency symbol return ls;} // Allow nested stream operations istream& operator>> (istream& ls, money& rs) { double temp_money; ls >> temp_money; rs = temp_money; return ls; }