Solved

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

Posted on 2010-11-14
27
413 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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
countAbc challenge 9 50
word0 challenge 4 54
sorting efficency of sorting algorithm 30 83
python sqlite question 11 43
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The purpose of this article is to demonstrate how we can use conditional statements using Python.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

744 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

14 Experts available now in Live!

Get 1:1 Help Now