stack used for both floats and ints

Started by
14 comments, last by dragongame 18 years, 8 months ago
For an interpreter written in C++ for an esoteric programming language, I want to have a stack of floating point numbers. So I want it to have the behaviour as if it's a floating point stack that converts floating point numbers to int when needed and converts them back to float when pushing them again. But, the disadvantage of this is the performance loss when you're working with only ints. What's a good way to make this so that it supports both ints and floats, and only converts it when needed, and so that to the user of this stack it seems as if it's floating point all the time?
Advertisement
How about using a universal type stack and 1 specific type to store all data?

enum ScriptType { ST_INT = 0, ST_FLOAT, ST_OBJECT };struct DataType{    ScriptType Type;    int    Integer;    float  Float;    void  *Object;};


Then, when pushing the type:
DataType t;t.Type = ST_INT;t.Integer = 10;stack.push(t);


You have both the speed and reusability. It uses some more memory, but it's pretty efficient.

Toolmaker

I dunno, I suppose you could make a wrapper structure use a union and a flag to say which type is actually stored (int or float). That seems a bit yucky to me though.

It's hard to say... it might be helpful to first of all prioritise for us what is more important to you... time to insert a value or time to read? Space or speed?

I would also say just program it how you think it should look, and then identify if it really is a big performance hit to do it a simple way (like storing floats in an stl stack, and converting when necessary)

(EDIT: Toolmaker's idea is valid, this is speed of access at expense of time to insert and space)
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.
class StackData{public:    virtual float operator()()=0;    virtual int operator()()=0;    virtual StackData& operator=(float f)=0;    virtual StackData& operator=(int i)=0;};template <typename T>class StackDataT : public StackData{public:   float operator()() { return (float)_t; }   int operator()() { return (int)_t; }   StackData& operator=(float f) { _t = (T)f; return this; }   StackData& operator=(int i)   { _t = (T)i; return this; }private:   T _t;};// or you could useclass StackData{public:   float operator()() { if(_asFloat) return _d.f; else return (float)_d.i; }   int operator()() { if(_asFloat) return (int)_d.f; else return _d.i; }   StackData& operator=(float f) { _d.f = f; _asFloat = true; return this; }   StackData& operator=(int i)   { _d.i = i; _asFloat = false; return this; }private:   bool _asFloat;   union   {      float f;      int i;   } _d;};


and now just use StackData instead of the float you normaly would use.

Hope this helps.
“Always programm as if the person who will be maintaining your program is a violent psychopath that knows where you live”
Thanks, out of the ideas I've made something, but not with an union, with both int and float stored at the same time:

class IntFloat{    private:    int i;    float f;    bool iu; //int up to date    bool fu; //float up to date        public:    void seti(int i)    {        this->i = i;        iu = 1;        fu = 0;    }    void setf(float f)    {        this->f = f;        iu = 0;        fu = 1;    }    int geti()    {        if(iu == 0) {i = int(f); iu = 1;}        return i;    }    float getf()    {        if(fu == 0) {f = float(i); fu = 1;}        return f;    }};
Hi,

your int(f) should be (int)f;
that looks like it's fast.
you could even overload the operators:

class IntFloat{//...    IntFloat& operator=(float f) { setf( f ); return this; }    IntFloat& operator=(int i)   { seti( i ); return this; }};IntFloat var;var = 1;var = 3.0f;
“Always programm as if the person who will be maintaining your program is a violent psychopath that knows where you live”
Quote:Original post by dragongame
Hi,
your int(f) should be (int)f;


Actually, it's fine the way it is. C++ supports two different styles of casting, and I'm surprised you haven't seen this method before.

{[JohnE, Chief Architect and Senior Programmer, Twilight Dragon Media{[+++{GCC/MinGW}+++{Code::Blocks IDE}+++{wxWidgets Cross-Platform Native UI Framework}+++
Why should int(f) be (int)f? Is there a difference?
Nope, each one does the exact same thing by saying you want to cast to an int. Use whichever you prefer.
{[JohnE, Chief Architect and Senior Programmer, Twilight Dragon Media{[+++{GCC/MinGW}+++{Code::Blocks IDE}+++{wxWidgets Cross-Platform Native UI Framework}+++
Okay,

i only knew the C cast style (int)bla and the C++ cast style static_cast<>() and the like.
okay ... int(bla) is much cleaner looking, I just have never seen it.
Every day you lern some thing.
“Always programm as if the person who will be maintaining your program is a violent psychopath that knows where you live”

This topic is closed to new replies.

Advertisement