Root::Root(Number& base, Number& root) { this->base = &base; this->root = &root; if (typeid(*this->root) == typeid(Placeholder) && (typeid(*this->base) == typeid(Placeholder) || typeid(*this->base) == typeid(Integer))) { Placeholder * cast = dynamic_cast<Placeholder*>(this->root); for (int i = 0; i < cast->getOperators().size(); i++) { if (cast->getOperators().at(i) == '/') { if (typeid(cast->getNumbers().at(i + 1)) == typeid(Integer)) { Integer * intCast = dynamic_cast<Integer*>(cast->getNumbers().at(i + 1)); if (typeid(*this->base) == typeid(Placeholder)) { Placeholder * baseCast = dynamic_cast<Placeholder*>(this->base); for (int x = 0; x < baseCast->getNumbers().size(); x++) { if (typeid(*baseCast->getNumbers().at(x)) == typeid(Integer)) { Integer * baseInt = dynamic_cast<Integer*>(baseCast->getNumbers().at(x)); if (intCast->getInt() % 2 == 0 && baseInt < 0) { throw std::out_of_range("A negative number cannot be applied to an even root. SOURCE: " + this->toString()); } } } } else if (typeid(*this->base) == typeid(Integer)) { Integer * baseInt = dynamic_cast<Integer*>(this->base); if (intCast->getInt() % 2 == 0 && baseInt < 0) { throw std::out_of_range("A negative number cannot be applied to an even root. SOURCE: " + this->toString()); } } } } } } }
std::string Root::toString() { if (typeid(*this->root) == typeid(Integer)) { Integer * intRoot = dynamic_cast<Integer*>(this->root); if (intRoot->getInt() == 2) { return "sqrt:(" + this->base->toString() + ")"; } else if (intRoot->getInt() < 0 && typeid(*this->base) == typeid(Placeholder)) { return "(" + this->root->toString() + ")rt:" + this->base->toString(); } else if (intRoot->getInt() < 0 && typeid(*this->base) != typeid(Placeholder)) { return "(" + this->root->toString() + ")rt:(" + this->base->toString() + ")"; } } else if (typeid(*this->root) == typeid(Placeholder) && typeid(*this->base) == typeid(Placeholder)) { return "(" + this->root->toString() + ")rt:" + this->base->toString(); } else if (typeid(*this->root) == typeid(Placeholder) && typeid(*this->base) != typeid(Placeholder)) { return "(" + this->root->toString() + ")rt:(" + this->base->toString() + ")"; } return this->root->toString() + "rt:(" + this->base->toString() + ")"; }
Number* Fraction::subtract(Number* F1){ Fraction* f1 = dynamic_cast<Fraction*>(F1); Fraction* f2 = dynamic_cast<Fraction*>(this); if(f1 && f2){ Number* n1 = f1->getNumerator(); Number* n2 = f2->getNumerator(); Number* d1 = f1->getDenominator(); Number* d2 = f2->getDenominator(); Integer* i1 = dynamic_cast<Integer*>(n1); Integer* i2 = dynamic_cast<Integer*>(n2); Integer* i3 = dynamic_cast<Integer*>(d1); Integer* i4 = dynamic_cast<Integer*>(d2); if(i1 && i2 && i3 && i4){ Number* lcm = f2->lcd(f1); Integer* lcd = dynamic_cast<Integer*>(lcm); int t1 = i1->getInt(); int t2 = i2->getInt(); int t3 = i3->getInt(); int t4 = i4->getInt(); int lcmint = lcd->getInt(); int fact1 = lcmint / t1; int fact2 = lcmint / t2; t1 *= fact1; t3 *= fact1; t2 *= fact2; t4 *= fact2; int diff = t3 - t4; Integer* newNum = new Integer(diff); Integer* newDen = new Integer(lcmint); Fraction* ans = new Fraction(newNum, newDen); Number* simpleAns = ans->simplify(); return simpleAns; } else return F1; } else return F1; }
Number& Variable::operator/(Number& rhs) { if (typeid(rhs) == typeid(Variable)) { Variable * rhsCastVar = dynamic_cast<Variable*>(&rhs); if (rhsCastVar->var == this->var) { Number * result = new Integer(1); delete rhsCastVar; return *result; } else { std::vector<Number*> numbers; std::vector<char> operators; numbers.push_back(this); numbers.push_back(&rhs); operators.push_back('/'); Number * result = new Placeholder(numbers, operators); delete rhsCastVar; return *result; } } else if (typeid(rhs) == typeid(Exponent)) { Exponent * rhsCastExp = dynamic_cast<Exponent*>(&rhs); if (typeid(rhsCastExp->getBase()) == typeid(Variable)) { Variable * rhsCastVar = dynamic_cast<Variable*>(&rhsCastExp->getBase()); if (rhsCastVar->var == this->var) { if (typeid(rhsCastExp->getExponent()) == typeid(Integer)) { Integer * integer = dynamic_cast<Integer*>(&rhsCastExp->getExponent()); Number * newExpInt = new Integer(integer->getInt() - 1); Exponent * exponent = new Exponent(*this, *newExpInt); delete integer; delete rhsCastVar; delete rhsCastExp; return *exponent; } } delete rhsCastVar; } delete rhsCastExp; } std::vector<Number*> numbers; std::vector<char> operators; numbers.push_back(this); numbers.push_back(&rhs); operators.push_back('/'); Number * result = new Placeholder(numbers, operators); return *result; }
Fraction::Fraction(Number* numerator, Number* denominator){ //sets fraction if passed Number object this->numerator = numerator; Integer* i = dynamic_cast<Intger*>(denominator); try{ if(i->getInt() == 0){ throw invalid_argument("Zero in denominator"); } else{ this->denominator = denominator; } } catch(exception& e){ cerr << "ERROR:" << e.what; } }
Number& Root::simplify(){ if (typeid(*base) == typeid(Integer) && typeid(*root) == typeid(Integer)) { Integer * baseInt = dynamic_cast<Integer*>(base); Integer * rootInt = dynamic_cast<Integer*>(root); bool isRootNeg = false; bool isBaseNeg = false; if (rootInt->getInt() < 0) { isRootNeg = true; int newRoot = rootInt->getInt() * -1; delete rootInt; root = new Integer(newRoot); rootInt = new Integer(newRoot); } else if (rootInt->getInt() == 0) { throw std::out_of_range("The value of n for an n'th root object cannot be 0. SOURCE: " + this->toString()); } if (baseInt->getInt() < 0 && rootInt->getInt() % 2 != 0) { isBaseNeg = true; int newBase = baseInt->getInt() * -1; delete baseInt; base = new Integer(newBase); baseInt = new Integer(newBase); } else if (baseInt->getInt() == 0) { return *(new Integer(0)); } else if (baseInt->getInt() < 0 && rootInt->getInt() % 2 == 0) { throw std::out_of_range("A negative number cannot be applied to an even root. SOURCE: " + this->toString()); } std::vector<int*> vec = primeFactors(baseInt->getInt()); double invRoot = 1 / ((double)rootInt->getInt()); if ((int)pow(baseInt->getInt(), invRoot) == pow(baseInt->getInt(), invRoot)) { if (isRootNeg) { Integer * one = new Integer(1); Placeholder * ph = new Placeholder(); ph->getNumbers().push_back(one); if (isBaseNeg) { ph->getNumbers().push_back(new Integer(pow(baseInt->getInt(), invRoot) * -1)); } else { ph->getNumbers().push_back(new Integer(pow(baseInt->getInt(), invRoot))); } ph->getOperators().push_back('/'); return *ph; } if (isBaseNeg) { Number * toReturn = (new Integer(pow(baseInt->getInt(), invRoot) * -1)); return *toReturn; } else { Number * toReturn = (new Integer(pow(baseInt->getInt(), invRoot))); return *toReturn; } } int multiplier = 1; int innerValue = 1; for (int i = 1; i < vec.size(); i++) { int exp = vec.at(i)[1]; int multiplierExp = 0; for (int x = 0; x < vec.at(i)[1]; x++) { if (exp - rootInt->getInt() >= 0) { exp = exp - rootInt->getInt(); multiplierExp++; } else { x = vec.at(i)[1]; } } vec.at(i)[1] = exp; multiplier *= pow(vec.at(i)[0], multiplierExp); innerValue *= pow(vec.at(i)[0], vec.at(i)[1]); } if (multiplier > 1) { if (innerValue == 1) { Number * toReturn = new Integer(multiplier); return *toReturn; } if (isRootNeg) { Integer * one = NULL; if (isBaseNeg) { one = new Integer(1); } else { one = new Integer(-1); } Placeholder * simplified = new Placeholder(); simplified->getNumbers().push_back(new Integer(multiplier)); delete base; this->base = new Integer(innerValue); simplified->getNumbers().push_back(&this->clone()); simplified->getOperators().push_back('*'); Placeholder * ph = new Placeholder(); ph->getNumbers().push_back(one); ph->getNumbers().push_back(simplified); ph->getOperators().push_back('/'); return *ph; } Placeholder * simplified = new Placeholder(); if (isBaseNeg) { simplified->getNumbers().push_back(new Integer(multiplier * -1)); } else { simplified->getNumbers().push_back(new Integer(multiplier)); } delete base; this->base = new Integer(innerValue); simplified->getNumbers().push_back(&this->clone()); simplified->getOperators().push_back('*'); return *simplified; } return this->clone(); } else if (typeid(*root) == typeid(Placeholder)) { Placeholder * rootPlaceholder = dynamic_cast<Placeholder*>(root); if (typeid(rootPlaceholder->getNumbers().at(0)) == typeid(Integer)) { Integer * negRootInt = dynamic_cast<Integer*>(rootPlaceholder->getNumbers().at(0)); Integer * rootInt = dynamic_cast<Integer*>(rootPlaceholder->getNumbers().at(1)); if (negRootInt->getInt() == -1) { Placeholder * ph = new Placeholder(); Integer * one = new Integer(1); ph->getNumbers().push_back(one); ph->getNumbers().push_back(&rootInt->clone()); ph->getOperators().push_back('/'); Exponent * exp = new Exponent(base->clone(), *ph); return *exp; } else { return this->clone(); } } else { return this->clone(); } } else if (typeid(*base) == typeid(Placeholder)) { Placeholder * basePlaceholder = dynamic_cast<Placeholder*>(base); if (typeid(basePlaceholder->getNumbers().at(0)) == typeid(Integer)) { Integer * negBaseInt = dynamic_cast<Integer*>(basePlaceholder->getNumbers().at(0)); if (typeid(*root) == typeid(Integer)) { Integer * rootInt = dynamic_cast<Integer*>(root); if (negBaseInt->getInt() < 0 && rootInt->getInt() % 2 == 0) { throw std::out_of_range("A negative number cannot be applied to an even root. SOURCE: " + this->toString()); } } } } else { return this->clone(); } }
// **NOTICE**: In order to avoid circular referencing, this method must be copy and pasted as opposed to // being inherited from the Number class. bool Root::operator==(Number& rhs) { if (typeid(*this) == typeid(rhs)) { if (typeid(rhs) == typeid(Exponent)) { Exponent * rhsCast = dynamic_cast<Exponent*>(&rhs); Exponent * lhsCast = dynamic_cast<Exponent*>(this); if (rhsCast->getBase() == lhsCast->getBase() && rhsCast->getExponent() == lhsCast->getExponent()) { return true; } else { return false; } } else if (typeid(rhs) == typeid(Log)) { Log * rhsCast = dynamic_cast<Log*>(&rhs); Log * lhsCast = dynamic_cast<Log*>(this); if (rhsCast->getBase() == lhsCast->getBase() && rhsCast->getArgument() == lhsCast->getArgument()) { return true; } else { return false; } } else if (typeid(rhs) == typeid(Placeholder)) { Placeholder * rhsCast = dynamic_cast<Placeholder*>(&rhs); Placeholder * lhsCast = dynamic_cast<Placeholder*>(this); if (rhsCast->getNumbers().size() == lhsCast->getNumbers().size()) { for (int i = 0; i < lhsCast->getNumbers().size(); i++) { bool matched = false; for (int y = 0; y < rhsCast->getNumbers().size(); y++) { if (lhsCast[i] == rhsCast[y]) { matched = true; } } if (!matched) { return false; } } for (int i = 0; i < lhsCast->getOperators().size(); i++) { bool matched = false; for (int y = 0; y < rhsCast->getOperators().size(); y++) { if (lhsCast->getOperators()[i] == rhsCast->getOperators()[y]) { if (lhsCast->getOperators()[i] == '-' || lhsCast->getOperators()[i] == '/') { if (lhsCast->getNumbers()[i] == rhsCast->getNumbers()[y] && lhsCast->getNumbers()[i+1] == rhsCast->getNumbers()[y+1]) { matched = true; } else { matched = false; } } else { if (lhsCast->getNumbers()[i] == rhsCast->getNumbers()[y] && lhsCast->getNumbers()[i+1] == rhsCast->getNumbers()[y+1]) { matched = true; } else if (lhsCast->getNumbers()[i+1] == rhsCast->getNumbers()[y] && lhsCast->getNumbers()[i] == rhsCast->getNumbers()[y+1]) { matched = true; } else { matched = false; } } } } if (!matched) { return false; } } return true; } else { return false; } } else if (typeid(rhs) == typeid(Root)) { Root * rhsCast = dynamic_cast<Root*>(&rhs); Root * lhsCast = dynamic_cast<Root*>(this); if (rhsCast->getBase() == lhsCast->getBase() && rhsCast->getRoot() == lhsCast->getRoot()) { return true; } else { return false; } } else if (typeid(rhs) == typeid(Integer)) { Integer * rhsCast = dynamic_cast<Integer*>(&rhs); Integer * lhsCast = dynamic_cast<Integer*>(this); if (rhsCast->getInt() == lhsCast->getInt()) { return true; } else { return false; } } else if (typeid(rhs) == typeid(Variable)) { Variable * rhsCast = dynamic_cast<Variable*>(&rhs); Variable * lhsCast = dynamic_cast<Variable*>(this); if (lhsCast->getVariable() == rhsCast->getVariable()) { return true; } else { return false; } } else { return false; } } else { return false; } }
Number* Fraction::divide(Number* F1){ Fraction* f1 = dynamic_cast<Fraction*>(F1); Fraction* f2 = dynamic_cast<Fraction*>(this); if(f1 && f2){ Number* n1 = f1->getNumerator(); Number* n2 = f2->getNumerator(); Number* d1 = f1->getDenominator(); Number* d2 = f2->getDenominator(); Integer* i1 = dynamic_cast<Integer*>(n1); Integer* i2 = dynamic_cast<Integer*>(n2); Integer* i3 = dynamic_cast<Integer*>(d1); Integer* i4 = dynamic_cast<Integer*>(d2); Number* newNum; Number* newDen; if(i3 && i2){ int t3 = i3->getInt(); int t4 = i2->getInt(); } else{ newNum = n1->multiply(d2); } if(i1 && i4){ int t1 = i1->getInt(); int t2 = i4->getInt(); newDen = new Integer(t1*t2); } else{ newNum = d1->multiply(n2); } Fraction ans = new Fraction(newNum, newDen); Number* simpleans = ans->simplify(); return simpleans; } Number* Fraction::simplify() { for (int i = denominator * numerator; i > 1; i--) { if ((denominator % i == 0) && (numerator % i == 0)) { denominator /= i; numerator /= i; } } } string Fraction::toString(){ ostringstream fraction; Fraction* f = dynamic_cast<Fraction*> (this); if(f){ Number* n = f->getNumerator(); Number* d = f->getDenominator(); Integer* num = dynamic_cast<Integer*>(n); Integer* den = dynamic_cast<Integer*>(d); int numerator = num->getInt(); int denominator = num->getInt(); fraction << " ( " << numerator << " / " << denominator << " ) "; return fraction.str(); } }
Number& Placeholder::operator+(Number& rhs) { if (typeid(rhs) == typeid(Placeholder)) { Placeholder * rhsCast = dynamic_cast<Placeholder*>(&rhs); std::vector<Number*> rhsNumberList = rhsCast->getNumbers(); std::vector<char> rhsOperatorList = rhsCast->getOperators(); for (int i = 0; i < rhsNumberList.capacity(); i++) { Number * addition = &(*this + *rhsNumberList[i]); if (typeid(addition) == typeid(Placeholder)) { Placeholder * tempPlaceholder = dynamic_cast<Placeholder*>(addition); this->numbers = &tempPlaceholder->getNumbers(); this->operators = &tempPlaceholder->getOperators(); } else { this->numbers->clear(); this->operators->clear(); this->numbers->push_back(addition); } } if (this->numbers->capacity() == 1) { return *this->numbers->at(0); } else { return *this; } } else if (typeid(rhs) == typeid(Exponent)) { Exponent * rhsCast = dynamic_cast<Exponent*>(&rhs); for (int i = 0; i < this->numbers->capacity(); i++) { if (i != 0 && this->operators->at(i-1) == '/') { break; } else if ((i == 0 && this->operators->at(0) == '/') || (i != 0 && this->operators->at(i - 1) == '/')) { Number * toAdd = &(*this->numbers->at(i + 1) * *rhsCast); Number * result = &(*this->numbers->at(i) + *toAdd); return *result; } else if (typeid(this->numbers[i]) == typeid(Exponent)) { Exponent * lhsCast = dynamic_cast<Exponent*>(this->numbers->at(i)); if (this->operators->at(i) == '*' || (i != 0 && this->operators->at(i-1) == '*')) { this->numbers->push_back(&rhs); this->operators->push_back('+'); delete rhsCast; delete lhsCast; return *this; } else if (lhsCast->getBase() == rhsCast->getBase() && lhsCast->getExponent() == rhsCast->getExponent()){ this->numbers->insert(this->numbers->begin() + i - 1, new Integer(2)); this->operators->insert(this->operators->begin() + i - 2, '*'); delete rhsCast; delete lhsCast; return *this; } } else if (i == this->numbers->capacity() - 1) { this->numbers->push_back(&rhs); this->operators->push_back('+'); delete rhsCast; return *this; } } } else if (typeid(rhs) == typeid(Integer)) { Integer * rhsCast = dynamic_cast<Integer*>(&rhs); for (int i = 0; i < this->numbers->capacity(); i++) { if (i != 0 && this->operators->at(i-1) == '/') { break; } else if ((i == 0 && this->operators->at(0) == '/') || (i != 0 && this->operators->at(i - 1) == '/')) { Number * toAdd = &(*this->numbers->at(i + 1) * *rhsCast); Number * result = &(*this->numbers->at(i) + *toAdd); return *result; } else if (typeid(this->numbers[i]) == typeid(Exponent)) { Integer * lhsCast = dynamic_cast<Integer*>(this->numbers->at(i)); this->numbers->assign(i, new Integer(lhsCast->getInt() + rhsCast->getInt())); return *this; } else if (i == this->numbers->capacity() - 1) { this->numbers->push_back(&rhs); this->operators->push_back('+'); delete rhsCast; return *this; } } } else if (typeid(rhs) == typeid(Log)) { Log * rhsCast = dynamic_cast<Log*>(&rhs); for (int i = 0; i < this->numbers->capacity(); i++) { if (i != 0 && this->operators->at(i-1) == '/') { break; } else if ((i == 0 && this->operators->at(0) == '/') || (i != 0 && this->operators->at(i - 1) == '/')) { Number * toAdd = &(*this->numbers->at(i + 1) * *rhsCast); Number * result = &(*this->numbers->at(i) + *toAdd); return *result; } else if (typeid(this->numbers[i]) == typeid(Log)) { Log * lhsCast = dynamic_cast<Log*>(this->numbers->at(i)); if (this->operators->at(i) == '*' || (i != 0 && this->operators->at(i-1) == '*')) { this->numbers->push_back(&rhs); this->operators->push_back('+'); delete rhsCast; delete lhsCast; return *this; } else if (lhsCast->getBase() == rhsCast->getBase() && lhsCast->getArgument() == rhsCast->getArgument()){ this->numbers->insert(this->numbers->begin() + i - 1, new Integer(2)); this->operators->insert(this->operators->begin() + i - 2, '*'); delete rhsCast; delete lhsCast; return *this; } } else if (i == this->numbers->capacity() - 1) { this->numbers->push_back(&rhs); this->operators->push_back('+'); delete rhsCast; return *this; } } } else if (typeid(rhs) == typeid(Root)) { Root * rhsCast = dynamic_cast<Root*>(&rhs); for (int i = 0; i < this->numbers->capacity(); i++) { if (i != 0 && this->operators->at(i-1) == '/') { break; } else if ((i == 0 && this->operators->at(0) == '/') || (i != 0 && this->operators->at(i - 1) == '/')) { Number * toAdd = &(*this->numbers->at(i + 1) * *rhsCast); Number * result = &(*this->numbers->at(i) + *toAdd); return *result; } else if (typeid(this->numbers[i]) == typeid(Root)) { Root * lhsCast = dynamic_cast<Root*>(this->numbers->at(i)); if (this->operators->at(i) == '*' || (i != 0 && this->operators->at(i-1) == '*')) { this->numbers->push_back(&rhs); this->operators->push_back('+'); delete rhsCast; delete lhsCast; return *this; } else if (lhsCast->getBase() == rhsCast->getBase() && lhsCast->getRoot() == rhsCast->getRoot()){ this->numbers->insert(this->numbers->begin() + i - 1, new Integer(2)); this->operators->insert(this->operators->begin() + i - 2, '*'); delete rhsCast; delete lhsCast; return *this; } } else if (i == this->numbers->capacity() - 1) { this->numbers->push_back(&rhs); this->operators->push_back('+'); delete rhsCast; return *this; } } } else if (typeid(rhs) == typeid(Variable)) { Variable * rhsCast = dynamic_cast<Variable*>(&rhs); for (int i = 0; i < this->numbers->capacity(); i++) { if (i != 0 && this->operators->at(i-1) == '/') { break; } else if ((i == 0 && this->operators->at(0) == '/') || (i != 0 && this->operators->at(i - 1) == '/')) { Number * toAdd = &(*this->numbers->at(i + 1) * *rhsCast); Number * result = &(*this->numbers->at(i) + *toAdd); return *result; } else if (typeid(this->numbers[i]) == typeid(Variable)) { Variable * lhsCast = dynamic_cast<Variable*>(this->numbers->at(i)); if (this->operators->at(i) == '*' || (i != 0 && this->operators->at(i-1) == '*')) { this->numbers->push_back(&rhs); this->operators->push_back('+'); delete rhsCast; delete lhsCast; return *this; } else if (lhsCast->getVariable() == rhsCast->getVariable()){ this->numbers->insert(this->numbers->begin() + i - 1, new Integer(2)); this->operators->insert(this->operators->begin() + i - 2, '*'); delete rhsCast; delete lhsCast; return *this; } } else if (i == this->numbers->capacity() - 1) { this->numbers->push_back(&rhs); this->operators->push_back('+'); delete rhsCast; return *this; } } } }