// Adds number to this and returns the sum // // Parameters: // shared_ptr<AbstractNumber> number number being added // // Returns: // shared_ptr<AbstractNumber> resulting sum of addition tr1::shared_ptr<AbstractNumber> Exponent::add(tr1::shared_ptr<AbstractNumber> number){ // Checks for cancellation number = number->simplify(); if(abs(toDouble() - number->toDouble()) < 0.000001 && this->getSign() != number->getSign()){ tr1::shared_ptr<AbstractNumber> r(new SmartInteger(0)); return r; } // Checks for duplication/simplification else if(abs(toDouble() - number->toDouble()) < 0.000001 && this->getSign() == number->getSign()){ vector< tr1::shared_ptr<AbstractNumber> > MultVector; tr1::shared_ptr<AbstractNumber> i(new SmartInteger(2)); MultVector.push_back(i); tr1::shared_ptr<AbstractNumber> me(new Exponent(base, power, sign)); MultVector.push_back(me); tr1::shared_ptr<AbstractNumber> r(new MultExpression(MultVector, '+')); return r; } //Can't tell if they add or not else if(number->getName() == "SumExpression" || number->getName() == "MultExpression"){ return number->add(shared_from_this()); } // Duplication necessary for simplification // Assuming number is in simplest form // No simplification possible else{ vector< tr1::shared_ptr<AbstractNumber> > SumVector; tr1::shared_ptr<AbstractNumber> me(new Exponent(base, power, sign)); SumVector.push_back(me); SumVector.push_back(number); tr1::shared_ptr<AbstractNumber> r(new SumExpression(SumVector)); return r; } }
// Multiplies number by this and returns the product // // Parameters: // shared_ptr<AbstractNumber> number number being multiplied // // Returns: // shared_ptr<AbstractNumber> resulting product of multiplication tr1::shared_ptr<AbstractNumber> Exponent::multiply(tr1::shared_ptr<AbstractNumber> number){ // Checks for simplification if both exponents number = number->simplify(); if(number->getName() == "Exponent"){ tr1::shared_ptr<Exponent> givenNumber = tr1::static_pointer_cast<Exponent>(number); if(abs(givenNumber->getValue("base")->toDouble() - base->toDouble()) < 0.000001){ tr1::shared_ptr<AbstractNumber> r(new Exponent(base, power->add(givenNumber->getValue("power")), this->calcSign(number))); return r; } else if (number->getName() == "Radical") { if (abs(number->getValue("value")->toDouble() - base->toDouble()) < 0.000001 ) { std::vector< tr1::shared_ptr<AbstractNumber> > SumVector; tr1::shared_ptr<AbstractNumber> one(new SmartInteger(1)); tr1::shared_ptr<AbstractNumber> invertedRoot(new MultExpression(one, number->getValue("root")->noSign(), number->getValue("root")->getSign())); SumVector.push_back(power); SumVector.push_back(invertedRoot); tr1::shared_ptr<AbstractNumber> power(new SumExpression(SumVector)); tr1::shared_ptr<AbstractNumber> output(new Exponent(number->getValue("value")->noSign(), power, sign)); return output; } } else{ tr1::shared_ptr<AbstractNumber> me(new Exponent(base, power, sign)); tr1::shared_ptr<AbstractNumber> r(new MultExpression(me, number, this->calcSign(number))); return r; } } // Checks for simplification if number = base // Adds 1 to exponent else if(abs(number->toDouble() - base->toDouble()) < 0.000001 ){ tr1::shared_ptr<AbstractNumber> c(new SmartInteger(1)); tr1::shared_ptr<AbstractNumber> r(new Exponent(base, power->add(c), this->calcSign(number))); return r; } else if(number->getName() == "SumExpression" || number->getName() == "MultExpression") { return number->multiply(shared_from_this()); } vector< tr1::shared_ptr<AbstractNumber> > MultVector; tr1::shared_ptr<AbstractNumber> me(new Exponent(base, power, sign)); MultVector.push_back(me); MultVector.push_back(number); tr1::shared_ptr<AbstractNumber> r(new MultExpression(MultVector, '+')); return r; }
// Divides this by number and returns the product // // Parameters: // shared_ptr<AbstractNumber> number divisor // // Returns: // shared_ptr<AbstractNumber> resulting quotient of division tr1::shared_ptr<AbstractNumber> Exponent::divide(tr1::shared_ptr<AbstractNumber>number){ // Reverses sign if exponent and multiplies if(number->getName()=="Exponent"){ tr1::shared_ptr<Exponent> givenNumber = tr1::static_pointer_cast<Exponent>(number); if(givenNumber->getSign()=='-'){ tr1::shared_ptr<AbstractNumber> r(new Exponent(givenNumber->getValue("base"), givenNumber->getValue("power"))); return multiply(r); } else{ tr1::shared_ptr<AbstractNumber> nOne(new SmartInteger(-1)); tr1::shared_ptr<AbstractNumber> newPower = givenNumber->getValue("power")->multiply(nOne); tr1::shared_ptr<AbstractNumber> r(new Exponent(givenNumber->getValue("base"), newPower, givenNumber->getSign())); return multiply(r); } } // Subtracts 1 from power if base = number else if(number->toDouble() == base->toDouble()){ tr1::shared_ptr<AbstractNumber> c(new SmartInteger(-1)); tr1::shared_ptr<AbstractNumber> r(new Exponent(base, power->add(c), this->calcSign(number))); return r; } else if(number->getName() == "MultExpression") { tr1::shared_ptr<MultExpression> MultE = tr1::static_pointer_cast<MultExpression>(number); vector<tr1::shared_ptr<AbstractNumber> > MultENum = MultE->getNumerator(); vector<tr1::shared_ptr<AbstractNumber> > MultEDem = MultE->getDenominator(); if (MultEDem.size() == 0) { tr1::shared_ptr<AbstractNumber> one(new SmartInteger(1)); MultEDem.push_back(one); } tr1::shared_ptr<AbstractNumber> reversedMultE(new MultExpression(MultEDem, MultENum, '+')); return reversedMultE->multiply(shared_from_this()); } vector< tr1::shared_ptr<AbstractNumber> > NumVector; tr1::shared_ptr<AbstractNumber> me(new Exponent(base, power, sign)); NumVector.push_back(me); vector< tr1::shared_ptr<AbstractNumber> > DenVector; DenVector.push_back(number); tr1::shared_ptr<AbstractNumber> r(new MultExpression(NumVector, DenVector, this->calcSign(number))); return r; }
int main() { vector< tr1::shared_ptr<AbstractNumber> > ansHistory; vector<string> expHistory; bool menuLoop = true; int input = 0; int setAns; cout << "|||| WELCOME ||||" << endl; cout << "|||| TO OUR ||||" << endl; cout << "|||| CALCULATOR ||||" << endl; cout << " _____________________ " << endl; cout << "| _________________ |" << endl; cout << "| | 0 | |" << endl; cout << "| |_________________| |" << endl; cout << "| ___ ___ ___ ___ |" << endl; cout << "| | 7 | 8 | 9 | | + | |" << endl; cout << "| |___|___|___| |___| |" << endl; cout << "| | 4 | 5 | 6 | | - | |" << endl; cout << "| |___|___|___| |___| |" << endl; cout << "| | 1 | 2 | 3 | | x | |" << endl; cout << "| |___|___|___| |___| |" << endl; cout << "|_____________________|" << endl; while (menuLoop) { cout << "\nPlease enter one of the options below: " << endl; cout << "=================================================" << endl; cout << "1. Compute New Expression |" << endl; cout << "=================================================" << endl; cout << "2. Help |" << endl; cout << "=================================================" << endl; cout << "3. Review Previous Expressions and Answers |" << endl; cout << "=================================================" << endl; cout << "4. Quit |" << endl; cout << "=================================================\n" << endl; cin>>input; if ( !( (1 <= input) && (input <= 4) ) ) { cin.clear(); while (cin.get() != '\n'); cout << "\nNot a valid menu option. Please enter 1, 2, 3, or 4." << endl; continue; } switch (input) { case 1: { cin.ignore(); bool keepCompute = true; while (keepCompute) { string input2; cout << "Enter the expression to compute. (Type 'back' to go back to the main menu)" << endl; getline(cin, input2); if(input2 != "") { if (input2.find("back") != string::npos) { keepCompute = false; } else { try{ if(input2.rfind("ans") != std::string::npos) { unsigned found = input2.rfind("ans"); if (history == "") history = "0"; input2.replace(found, std::string("ans").length(), "(" + history + ")"); tr1::shared_ptr<AbstractNumber> num(new SumExpression(input2,true)); historyAns = num->simplify(); cout << "Result: \n" << historyAns->toString() << endl; ansHistory.push_back(historyAns); history = input2; expHistory.push_back(history); } else { tr1::shared_ptr<AbstractNumber> num(new SumExpression(input2,true)); historyAns = num->simplify(); cout << "Result: \n" << historyAns->toString() << endl; ansHistory.push_back(historyAns); history = input2; expHistory.push_back(history); } } catch(exception &msg) { cout << "***ERROR: "<< msg.what() << "***" << endl; } } } else { cout << "Result: Invalid Expression\n" << endl; } } break; } case 2: printHelp(); break; case 3: if(ansHistory.size() == 0) { cout << "Please enter some expressions before viewing this option." << endl; } else { cout << "The previous answer was: " << historyAns->toString() << endl; cout << "The previous answer as a decimal: " << historyAns->toDouble() << endl; cout << "This answer may be used in further calculations by using the keyword 'ans'" << endl; cout << "\nThe previous expressions and answers calculated are as follows: " << endl; for(int i=0; i<ansHistory.size(); i++) { cout << "(#" << (ansHistory.size()-i) << ")" << "Expression: " << expHistory[i] << endl; cout << "Answer: " << ansHistory[i]->toString() << "\n" << endl; } cout << "To set 'ans' to a previous expressions's answer, please enter the corresponding digit: " << endl; cin>>setAns; if(!( (1 <= setAns) && (setAns <= ansHistory.size()) )) { cin.clear(); while (cin.get() != '\n'); cout << "\nNot a valid menu option. Please enter 1-10." << endl; continue; } else if(((1 <= setAns) && (setAns <= ansHistory.size()))== 1) { history = ansHistory[ansHistory.size() - setAns]->toString(); } else { cout << "\nNot a valid menu option. Please enter 1-10." << endl; } } break; case 4: cout << "The calculator will now exit. Thank you!" << endl; menuLoop = false; break; } } }