Solved

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

Posted on 2010-11-14
27
415 Views
Last Modified: 2012-05-10
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;
};
0
Comment
Question by:NSing9
  • 12
  • 10
  • 2
  • +3
27 Comments
 
LVL 3

Accepted Solution

by:
logic_chopper earned 125 total points
ID: 34133047
Well I would use a class template, this way you can also avoid the cast to "int" which may create subtle problems with your program with loss of precision.

template <class T>
...
public:
    Literal(Tvalue)
    {
        this->value = value;
    }
    T evaluate()
    {
        return value;
    }
private:
    T value;
};
0
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 34133087
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.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 34133156
>> 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.)
0
 
LVL 8

Expert Comment

by:Subrat (C++ windows/Linux)
ID: 34133349

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
0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 34133741
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.
0
 

Author Comment

by:NSing9
ID: 34150905
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
      
0
 
LVL 32

Expert Comment

by:phoffric
ID: 34150967
If you post all your code, someone will be able to help you better.
0
 
LVL 3

Expert Comment

by:logic_chopper
ID: 34151002
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);
0
 

Author Comment

by:NSing9
ID: 34151024
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
0
 
LVL 32

Expert Comment

by:phoffric
ID: 34151051
>> 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

0
 
LVL 32

Expert Comment

by:phoffric
ID: 34151063
If Literal were a templated function rather than a class, then the compiler would try to figure out what code should be generated.
0
 

Author Comment

by:NSing9
ID: 34151308
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      
0
 
LVL 32

Expert Comment

by:phoffric
ID: 34151318
If you post all your code, someone will be able to help you better.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:NSing9
ID: 34151331
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;
}
0
 
LVL 32

Expert Comment

by:phoffric
ID: 34151335
You never showed your definition of Expression.
0
 

Author Comment

by:NSing9
ID: 34151352
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;
}
       
0
 
LVL 32

Expert Comment

by:phoffric
ID: 34151399
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.
0
 

Author Comment

by:NSing9
ID: 34151419
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

0
 

Author Comment

by:NSing9
ID: 34151426
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

0
 
LVL 32

Expert Comment

by:phoffric
ID: 34151454
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>
...
0
 

Author Comment

by:NSing9
ID: 34151499
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

0
 
LVL 32

Expert Comment

by:phoffric
ID: 34151573
The .h files are helpful. How about Operand, and any other .h useful for us to recreate your problem.
0
 

Author Comment

by:NSing9
ID: 34151625
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

0
 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 125 total points
ID: 34151674
Try this:
Expression* literal = new Literal<double>(value);

Open in new window

0
 
LVL 32

Expert Comment

by:phoffric
ID: 34151680
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.
0
 

Author Closing Comment

by:NSing9
ID: 34152473
Thank you!  This finally worked!
0
 
LVL 32

Expert Comment

by:phoffric
ID: 34152617
You're welcome.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Best book to learn C++ 4 70
Add values of each row in an array 3 50
Path to Python 9 103
FMX TCameraComponent Problem 2 48
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

947 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now