Link to home
Start Free TrialLog in
Avatar of NSing9
NSing9Flag for United States of America

asked on

How can a C++ class account for both double and floating points?

How can I account for both doubles and floating points using the following code:

public:
    Literal(double value)
    {
        this->value = value;
    }
    double evaluate()
    {
        return value;
    }
private:
    int value;
};
ASKER CERTIFIED SOLUTION
Avatar of logic_chopper
logic_chopper

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of TommySzalapski
Just make
int value
be
double value

You can set a double equal to a float, a double, or an int and it will keep the right value. It will always be correct up to, like, 12 decimal places.
Avatar of phoffric
phoffric

>> How can I account for both doubles and floating points
The above comments both make sense.
FYI - if you call  Literal(double value) with a float, then the compiler will promote tha value to a double with no loss in precision in this pass-by-value. (But, as mentioned, the int <- double statement can cause pecision loss.)

FYI:
By default all the real no.s are double.
Ex: 7.0 ----------------------------- > it's a double value not a float

To make it float you need to use suffix f
Ex: 7.0f  -------------------------------- > It's a float value
it also is a question of how you design your class. If the objects are going to be encapsulations of integers only and you don't foresee any changes which is highly unlikely then you should probably have your constructor interfaces reflecting this. So have a constructor which takes only an integer. Do some pre-processing to round off the float or double input you receive before passing it to the constructor.

float ft = somenum;
int it = ceil/floor(ft); //use ceil or floor depending on your needs.

call your constructor which takes an integer as argument.

Literal lt = Literal(it);

This approach also implies that you can overload your constructor to take a float argument in order to create an object which encapsulates float values.

Else the best approach to go for is to templatize the class as has been already pointed out by experts in previous posts.
Avatar of NSing9

ASKER

I have tried the Templae approach, but when I compile my pgoram I get an error message in another class that is associated with the Literal class referenced above.  The error in the other class is associated with this line of code:

Expression* literal = new Literal(value);

error C2955: 'Literal' : use of class template requires template argument list
error C2514: 'Literal' : class has no constructors
      
If you post all your code, someone will be able to help you better.
You will need to specify a template parameter, so for example, the code that you have shown could be changed to:
Expression<double>* literal = new Literal<double>(value);
Avatar of NSing9

ASKER

I have attached the two classes that I believe are affected by this change.  I don't want to attach everything because there are quite a few more.   The error message that I receive is associated with Literal in the operand.cpp file.
operand.cpp
literal.h
>> template <class T>
>> class Literal: public Operand
Given that Literal is a templated class, you need to let the compiler know what type to use. For example, with vector, you might say:


vector<int> myIntVector;

Open in new window

If Literal were a templated function rather than a class, then the compiler would try to figure out what code should be generated.
Avatar of NSing9

ASKER

Simply changing the line of code to:

Expression<double>* literal = new Literal<double>(value);

doesn't compile.  I get a few errors:

error C2143: syntax error : missing ';' before '<'
error C2143: syntax error : missing ';' before '<'      
error C2065: 'literal' : undeclared identifier      
If you post all your code, someone will be able to help you better.
Avatar of NSing9

ASKER

There are too many files to post.  I have already attached the two files where the changes are being made and that are generating the errors.  I will post the code for the file that is generating the error here:

#include <cctype>
#include <iostream>
#include <list>
#include <string>

using namespace std;

#include "expression.h"
#include "subexpression.h"
#include "operand.h"
#include "variable.h"
#include "literal.h"
#include "parse.h"

Expression* Operand::parse()
{
    char paren;
    double value;

    cin >> ws;
    if (isdigit(cin.peek()))
    {
        cin >> value;
        Expression<double>* literal = new Literal<double>(value);
        return literal;
    }
    if (cin.peek() == '(')
    {
        cin >> paren;
        return SubExpression::parse();
    }
    else
        return new Variable(parseName());
    return 0;
}
You never showed your definition of Expression.
Avatar of NSing9

ASKER

My apologies:

#include <iostream>
using namespace std;

#include "SyntaxException.h" // SyntaxException class

#include "expression.h"
#include "subexpression.h"
#include "operand.h"
#include "plus.h"
#include "minus.h"
#include "times.h"
#include "divide.h"

SubExpression::SubExpression(Expression* left, Expression* right)
{
    this->left = left;
    this->right = right;
}

Expression* SubExpression::parse()
{
    Expression* left;
    Expression* right;
    char operation, paren;
   
    left = Operand::parse();
    cin >> operation;
    right = Operand::parse();
    cin >> paren;
      switch (operation)
    {
        case '+':
            return new Plus(left, right);
        case '-':
            return new Minus(left, right);
        case '*':
            return new Times(left, right);
        case '/':
            return new Divide(left, right);
            default:
                  throw SyntaxException();
    }
    return 0;
}
       
Could you show (in the code box) the file that defines the class Expression, SubExpression, and Variable. That may help. If there are other class definitions that are potentially involved in the errors, that may help.
Avatar of NSing9

ASKER

This is the same file that I posted in the previous comment.  So I hope I am posting it here correctly.
#include <iostream>
using namespace std;

#include "SyntaxException.h" // SyntaxException class

#include "expression.h"
#include "subexpression.h"
#include "operand.h"
#include "plus.h"
#include "minus.h"
#include "times.h"
#include "divide.h"

SubExpression::SubExpression(Expression* left, Expression* right)
{
    this->left = left;
    this->right = right;
}

Expression* SubExpression::parse()
{
    Expression* left;
    Expression* right;
    char operation, paren;
    
    left = Operand::parse();
    cin >> operation;
    right = Operand::parse();
    cin >> paren;
      switch (operation)
    {
        case '+':
            return new Plus(left, right);
        case '-':
            return new Minus(left, right);
        case '*':
            return new Times(left, right);
        case '/':
            return new Divide(left, right);
            default:
                  throw SyntaxException(); 
    }
    return 0;
}

Open in new window

Avatar of NSing9

ASKER

Here is the variable class:
#include <strstream>
#include <vector>
using namespace std;

#include "UninitializedException.h" //
#include "expression.h"
#include "operand.h"
#include "variable.h"
#include "symboltable.h"

extern SymbolTable symbolTable;

double Variable::evaluate()
{
	if (symbolTable.lookUp(name) == -1)		//
		throw UninitializedException(name);		// terminate function

	return symbolTable.lookUp(name);
}

Open in new window

Yes, that makes posting code much easier, and now we can refer to line numbers. But the definitions of the classes Expression, SubExpression, and Variable are still not shown. They begin with, for example:

class Expression {
}

or if templated,
template <class T>
...
Avatar of NSing9

ASKER

I am new to C++ so forgive me for not understanding all of the terminology.  Since you are asking for definitions, I assume you are refering to the .h files.
class Expression
{
public: 
    virtual double evaluate() = 0;
};

class SubExpression: public Expression
{
public:
    SubExpression(Expression* left, Expression* right);
    static Expression* parse();
protected: 
    Expression* left;
    Expression* right;
};


class Variable: public Operand
{
public:
    Variable(string name)
    {
        this->name = name;
    }
    double evaluate();
private:
    string name;
};

Open in new window

The .h files are helpful. How about Operand, and any other .h useful for us to recreate your problem.
Avatar of NSing9

ASKER

I have inlcuded symboltable.h and operand.h.  Going back to my original post and another response that was received, would changing:

int value;
to
double value

in the Literal definition not suffice?


class Operand: public Expression
{
public:
    static Expression* parse();
};

class SymbolTable
{
public:
    SymbolTable() {}
    void insert(string variable, double value);
    double lookUp(string variable) const;
private:
    struct Symbol
    {
        Symbol(string variable, double value)
        {
            this->variable = variable;
            this->value = value;
        }
        string variable;
        double value;
    };

    vector<Symbol> elements;
};

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The previous similar posts made assumptions about the Expression class. But without your class definitions (which you put in your .h files), it was only reasonable guessing.
Avatar of NSing9

ASKER

Thank you!  This finally worked!
You're welcome.