#include "Money.h" #include using namespace std; /** Construct a new money instance. * Automatically normalizes so that cents is between -99 and 99 and so that * signs of the dollar and cents values do not disagree. * @param dollars value in dollars * @param cents value in cents (sign is assumed to match that of dollars) */ Money::Money(int dollars, int cents) { this->dollars = dollars; this->cents = cents; normalize(); } /** Return the amount of dollars. * * If overall value is negative, the returned amount will be appropriately negated. * * @return number of dollars (signed) */ int Money::getDollars() const { return dollars; } /** Return the amount of cents. * * If overall value is negative, the returned amount will be appropriately negated. * * @return number of cents (signed) */ int Money::getCents() const { return cents; } /** Checks if current value is negative. * @return true if negative, false otherwise */ bool Money::isNegative() const { return (dollars < 0 || cents < 0); } /** Binary addition of monetary values. * @param other monetary value as second operand * @return sum of monetary values */ Money Money::operator+(const Money& other) const { return Money(dollars + other.dollars, cents + other.cents); } /** Mutating form of addition for monetary values. * @param other monetary value as second operand */ void Money::operator+=(const Money& other) { dollars += other.dollars; cents += other.cents; normalize(); } /** Binary subtraction of monetary values. * @param other monetary value as second operand * @return difference of monetary values */ Money Money::operator-(const Money& other) const { return Money(dollars - other.dollars, cents - other.cents); } /** Mutating form of subtraction for monetary values. * @param other monetary value as second operand */ void Money::operator-=(const Money& other) { dollars -= other.dollars; cents -= other.cents; normalize(); } /** Unary negation of monetary value. * @return negation of original value */ Money Money::operator-() const { return Money(-dollars, -cents); }; /** Compares two monetary amounts * @param other monetary value as second operand * @return true if first is stricty less than second */ bool Money::operator<(const Money& other) const { return (dollars < other.dollars || (dollars == other.dollars && cents < other.cents)); }; /** Compares two monetary amounts * @param other monetary value as second operand * @return true if first is less than or equal to the second */ bool Money::operator<=(const Money& other) const { return ((*this == other) || (*this < other)); }; /** Compares two monetary amounts * @param other monetary value as second operand * @return true if first is stricty greater than second */ bool Money::operator>(const Money& other) const { return !(*this <= other); }; /** Compares two monetary amounts * @param other monetary value as second operand * @return true if first is greater than or equal to the second */ bool Money::operator>=(const Money& other) const { return !(*this < other); }; /** Compares two monetary amounts * @param other monetary value as second operand * @return true if two are equivalent */ bool Money::operator==(const Money& other) const { return (dollars == other.dollars && cents == other.cents); }; /** Compares two monetary amounts * @param other monetary value as second operand * @return true if two are non-equivalent */ bool Money::operator!=(const Money& other) const { return !(*this == other); }; /** Multiply monetary amount by a constant. * Rounds to nearest cent. * @param factor multiplicative factor * @return new monetary value */ Money Money::operator*(double factor) const { double pennies = 100.0 * (dollars + cents/100.0) * factor; pennies += (pennies >= 0 ? 0.5 : -0.5); long temp = long(pennies); return (temp >= 0 ? Money( temp/100, temp%100) : Money(- (-temp)/100, - (-temp%100))); } /** Multiply monetary amount by a constant. * Rounds to nearest cent. * @param factor multiplicative factor * @return new monetary value */ Money operator*(double factor, const Money& m) { return m * factor; // rely on the member form of operator } /** * Output the value in from such as $5.35 for positive value or * -$5.35 for a negative value. * @param os the output stream * @param value monetary value to display */ ostream& operator<<(ostream& os, const Money& value) { int d = value.getDollars(); int c = value.getCents(); if (d < 0 || c < 0) { os << "-"; d = -d; c = -c; } os << "$"; os << d; os << "."; os << setfill('0') << setw(2) << c; // force two characters, even if zero return os; } void Money::normalize() { while (cents >= 100) { dollars++; cents -= 100; } while (cents <= -100) { dollars--; cents += 100; } if (dollars < 0 && cents > 0) { cents -= 100; dollars += 1; } if (dollars > 0 && cents < 0) { cents += 100; dollars -= 1; } }