NumericLiteral NumericLiteral::operator/(const NumericLiteral &l) const {
    if (denominator == 0.0 || l.denominator == 0.0)
        throw UTComputerException("Error NumericLiteral::operator/(NumericLiteral &l) : one of the denominators is 0.");

    if (l.numerator == 0.0)
        throw UTComputerException("Error NumericLiteral::operator/(NumericLiteral &l) : l is 0 and division by zero is impossible.");

    /* if one of the arguments is real, we must return a
     * real literal with the result of the operation in the numerator attribute
     * and set the denominator to 1 */
    if (isReal() || l.isReal()) {
        NumericLiteral tmp = NumericLiteral(
                numerator*l.denominator,
                denominator * l.numerator
        );
        tmp.numerator = tmp.numerator/tmp.denominator;
        tmp.denominator = 1;
        return tmp;
    }

    /* In general, we return a new numeric literal with the normal division operation */
    return NumericLiteral(
            numerator*l.denominator,
            denominator * l.numerator
    );
}
Example #2
0
/*** OPERATEUR OR ***/
Entier& Rationnel::operatorOr(const Litteral& l) const{
    try {
        return l.operatorOr(*this);
    } catch (UTComputerException e) {
        throw UTComputerException(e.what());
    }
}
Example #3
0
/*** MODULO ***/
Litteral& Rationnel::operator%(const Litteral& l) const{
    try {
        return l%*this;
    } catch (UTComputerException e) {
        throw UTComputerException(e.what());
    }
}
Example #4
0
Litteral& Rationnel::operatorDivEntiere(const Rationnel& l)  const{
  /*  double tmp = l.getValue() / getValue();
    //on prend la partie entière. floor retourne un double. conversion auto entre double et int.
    int res = floor(tmp);
    return LitteralManager::getInstance().addEntier(res);*/
    throw UTComputerException("Il est impossible d'appliquer DIV entre deux rationnels.");
}
/* Tests done before in superclass :
 *      - test that pointer to stack is not null
 *      - test that stack contains enough Literal* (st.size() >= operator arity)
 *      - test that every Literal* unstacked isn't null
 *
 * OperatorSuperior applies to
 *      - two ComplexLiterals with no imaginary parts
 */
shared_ptr<Literal> OperatorSuperior::executeSpecificOperator() {
    try {
        Literal* a = arguments[0].get();
        Literal* b = arguments[1].get();
        ComplexLiteral* comp_a = dynamic_cast<ComplexLiteral*>(a);
        ComplexLiteral* comp_b = dynamic_cast<ComplexLiteral*>(b);

        // if the two literals are instance of ComplexLiteral
        if (comp_a != nullptr && comp_b != nullptr) {
            if (*comp_a > *comp_b) // then return a ComplexLiteral set to "integer" with a value of 1
                return shared_ptr<ComplexLiteral>(new ComplexLiteral(NumericLiteral(1.0)));
            else // then return a ComplexLiteral set to "integer" with a value of 0
                return shared_ptr<ComplexLiteral>(new ComplexLiteral(NumericLiteral(0.0)));
        }
        /* Note that the ComplexLiteral class throw exception if imaginary parts of both
         * arguments are different from 0*/

        // Here we didn't return anything or throw any exception, so both arguments have invalid type.
        throw UTComputerException("Error in OperatorSuperior::executeSpecificOperator : invalid literal types") ;
    }
    catch (UTComputerException e) {
        UTComputerException e1(e.getMessage());
        e1.insertBefore(" --> ");
        e1.insertBefore(arguments[1]->toString());
        e1.insertBefore(" and ");
        e1.insertBefore(arguments[0]->toString());
        e1.insertBefore("Error in applying OperatorSuperior on ");
        throw e1;
    }

}
/*
 * Address of stack must not be changed, but "st" do not point to a const stack : we use a constant pointer
 * and not a pointer to constant
 */
void OperatorLASTOP::execute(StackUTComputer * const st) {
    /*
     * Call to StackOperator::execute(st) :
     *      The super class function test that the current operator IS NOT "OperatorLASTOP" before setting
     *      StackUTComputer.lastOperator attribute to the current operator.
     *      Otherwise, we have an infinite loop :
     *          - setting last operator to OperatorLASTOP
     *          - calling this operator with st->getLastOperator()->execute(st)
     *          - setting last operator to OperatorLASTOP
     *          - ...
     * */
    StackOperator::execute(st); // check usual possible errors

    try {
        if (st->getLastOperator() != nullptr)
            st->getLastOperator()->execute(st);
        else
            throw UTComputerException("Error OperatorLASTOP::execute : StackUTComputer.lastOperator is null.");
    }
    catch (UTComputerException e) {
        UTComputerException e1(e.getMessage());
        e1.insertBefore(" --> ");
        e1.insertBefore("Error in applying OperatorLASTOP ");
        throw e1;
    }


}
void NumericLiteral::simplification() {
    if (!isRational())
        throw UTComputerException("Error NumericLiteral::simplification : simplifiaction on non retional literal is impossible.");

    // if numerator is 0, then set denominator to 1
    if (numerator == 0) {
        denominator = 1;
        return;
    }

    // denominator can't be 0
    if (denominator == 0) {
        throw UTComputerException("Error NumericLiteral::simplification : denominator can't be 0.");
    }

    /* Use of Euclide algorithm to find the greatest common divisor */
    double a=numerator, b=denominator;

    // we only works with positive values
    if (a<0)
        a=-a;
    if (b<0)
        b=-b;

    while(a != b) {
        if (a>b)
            a = a - b;
        else
            b = b - a;
    }

    // division of numerator and denominator by a, the greatest common divisor
    numerator /= a;
    denominator /= a;

    // if denominator is negative, pass the negation to the numerator
    if (denominator < 0) {
        denominator = -denominator;
        numerator = -numerator;
    }
}
// ===============================================================================================================
// ======================                         Override Methods                      ==========================
// ===============================================================================================================
string NumericLiteral::toString() const {
    ostringstream sting_stream;
    if (isInteger()) {
        sting_stream << (int) numerator;
        return sting_stream.str();
    }
    if (isRational()) {
        sting_stream << numerator << "/" << denominator;
        return sting_stream.str();
    }
    if (isReal()) {
        sting_stream << numerator;
        return sting_stream.str();
    }
    throw UTComputerException("Error NumericLiteral::toString() : literal isn't integer nor rational nor real");
}
Example #9
0
Entier& Rationnel::operator>=(const Complexe& l) const{
    throw UTComputerException("Impossible de comparer un rationnel et un complexe.");
}
Example #10
0
Litteral& Rationnel::operator$(const Complexe& l) const{
    throw UTComputerException("Impossible de creer un nombre complexe a partir d'un autre nombre complexe.");
}
Example #11
0
Litteral& Rationnel::operator%(const Complexe& l)  const{
    throw UTComputerException("Il est impossible d'appliquer MOD entre un complexe et un rationnel.");
}
Example #12
0
Litteral& Rationnel::operator%(const Rationnel& l) const{
    throw UTComputerException("Il est impossible d'appliquer MOD entre deux rationnels.");
}
/* Tests done before in superclass :
 *      - test that pointer to stack is not null
 *      - test that stack contains enough Literal* (st.size() >= operator arity)
 *      - test that every Literal* unstacked isn't null
 *
 * OperatorMultiplication applies to
 *      - two ComplexLiterals
 *      - two ExpressionLiteral
 *      - an ExpressionLiteral and a ComplexLiteral */
shared_ptr<Literal> OperatorMultiplication::executeSpecificOperator() {
    try {
        Literal* a = arguments[0].get();
        Literal* b = arguments[1].get();
        ComplexLiteral* comp_a = dynamic_cast<ComplexLiteral*>(a);
        ComplexLiteral* comp_b = dynamic_cast<ComplexLiteral*>(b);
        ExpressionLiteral* exp_a = dynamic_cast<ExpressionLiteral*>(a);
        ExpressionLiteral* exp_b = dynamic_cast<ExpressionLiteral*>(b);

        // if the two literals are instance of ComplexLiteral
        if (comp_a != nullptr && comp_b != nullptr)
            return *comp_a * *comp_b; // ComplexLiteral::operator*(ComplexLiteral &l) const


        // if the two literals are instance of ExpressionLiteral
        if (exp_a != nullptr && exp_b != nullptr)
            return *exp_a * *exp_b; // ExpressionLiteral::operator*(ExpressionLiteral &l) const


        /* If one of the two arguments isn't instance of ComplexLiteral then it must be instance of
         * ExpressionLiteral. Otherwise, it's an illegal argument.*/

        // if the first element is instance of ComplexLiteral but not the second
        if (comp_a != nullptr) {
            /* then b is not instance of ComplexLiteral (because of the first if statement) and can only be instance of
             * ExpressionLiteral. If not, then b is an illegal argument */
            if (exp_b != nullptr) {
                /* Multiplication between Complex and Expression is in fact multiplication between two Expression :
                 *      We have to create a temporary Expression with the Complex::toString() function
                 *      and then apply multiplication between the two Expression */
                ExpressionLiteral tmp(comp_a->toString());
                return tmp * *exp_b; // ExpressionLiteral::operator*(ExpressionLiteral &l) const
            }
            else {
                throw UTComputerException("Error in OperatorMultiplication::executeSpecificOperator : second argument has invalid type.");
            }
        }

        // if the second element is instance of ComplexLiteral but not the first
        if (comp_b != nullptr) {
            /* then a is not instance of ComplexLiteral (because of the first if statement) and can only be instance of
             * ExpressionLiteral. If not, then b is an illegal argument */
            if (exp_a != nullptr) {
                /* Multiplication between Complex and Expression is in fact multiplication between two Expression :
                 *      We have to create a temporary Expression with the Complex::toString() function
                 *      and then apply multiplication between the two Expression */
                ExpressionLiteral tmp(comp_b->toString());
                return *exp_a * tmp; // ExpressionLiteral::operator*(ComplexLiteral &l) const
            }
            else {
                throw UTComputerException("Error in OperatorMultiplication::executeSpecificOperator : first argument is of invalid type.");
            }
        }


        // Here we didn't return anything or throw any exception, so both arguments have invalid type.
        throw UTComputerException("Error in OperatorMultiplication::executeSpecificOperator : invalid literal types for both arguments");
    }
    catch (UTComputerException e) {
        UTComputerException e1(e.getMessage());
        e1.insertBefore(" --> ");
        e1.insertBefore(arguments[1]->toString());
        e1.insertBefore(" and ");
        e1.insertBefore(arguments[0]->toString());
        e1.insertBefore("Error in applying OperatorMultiplication on ");
        throw e1;
    }
}