By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,376 Members | 1,599 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,376 IT Pros & Developers. It's quick & easy.

Design issue... Question on best way to do it in C++.

P: n/a
Hi all,

Guess I wish to do some parsing for a calculator which might include
rational numbers.
So I can have integers (sequence of digits possibly started by -) and
rationals (two integers separated by '/').
I did a NumberWrapper which makes the use of a number, be it an integer
or rational transparent to the user.
Number(1, 2); represents 1/2
Number(2); represents 1

First issue, I have something like this in number (or would like to):
class Number {
....

private:
enum numberType {INTEGER, RATIONAL};
numberType type;
union {
int integer;
Rational rational; // Class defined by me...
};
};

Problem is Rational has non-trivial constructors so it just can't be
there. One way it to remove the union and just have an int and a
rational, never both are used at the same time (that wastes space but
saves me a lot of trouble).
Another way is to have a void* and then based on type I just cast it to
int or to rational as I need, obviously with caution, deleting and
freeing what I need. Well, this seems a lot of trouble!
Another is to just represent an integer as a rational with denominator
1 and forget the int or wrapper at all and use rationals all the way.

Another issue has to do with how to structure things around the
parsing. Bison uses unions for communication with flex so I have a
Number * in the union and whenever flex finds a rational or number,
allocates a new number and bison get's it so I can use it in parsing.
struct parsingState {
union {

Number *num;

};
ParsingStructureType type;
};
Problem is when I need to do some computations...
Guess I have Number *num; in the union and I want to update it to
become -num. I have defined operator-() in Number so I do:
parsingState ps;

....

ps->num = - ps->num;

It seems to be that this will leak right? (-ps->num) will allocate
another Number because operator-() is
Number Number::operator-() const;

and I'll lose my previous allocated number.
Any ideas on how I can do this or organize my structures?

Regards,

Paulo Matos

Nov 21 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a

Paulo Matos wrote:
Hi all,

Guess I wish to do some parsing for a calculator which might include
rational numbers.
So I can have integers (sequence of digits possibly started by -) and
rationals (two integers separated by '/').
I did a NumberWrapper which makes the use of a number, be it an integer
or rational transparent to the user.
Number(1, 2); represents 1/2
Number(2); represents 1

First issue, I have something like this in number (or would like to):
class Number {
...

private:
enum numberType {INTEGER, RATIONAL};
numberType type;
union {
int integer;
Rational rational; // Class defined by me...
};
};

Problem is Rational has non-trivial constructors so it just can't be
there. One way it to remove the union and just have an int and a
rational, never both are used at the same time (that wastes space but
saves me a lot of trouble).
Another way is to have a void* and then based on type I just cast it to
int or to rational as I need, obviously with caution, deleting and
freeing what I need. Well, this seems a lot of trouble!
Another is to just represent an integer as a rational with denominator
1 and forget the int or wrapper at all and use rationals all the way.
The safest way I found for this kind of a
problem is to use boost::variant

to start you up

typedef ::boost::variant<int, RationalNumber;

class plus_visitor : public boost::static_visitor<Number>
{
public:

Number operator()(int i, int j) const
{
return Number(i+j);
}

Number operator()(Rational const & i, Rational const & j) const
{
//suppose you have + op for Rational
return Number(i+j);
}

Number operator()(Rational const & i, int j) const
{
// suppose your rational has a constructor
// like Rational(int nominator, int denominator
return Number(Rational(i.nominator+j*i.denominator, i.denominator));
}

Number operator()(int i, Rational const & j) const
{
return Number(Rational(j.nominator+i*j.denominator, j.denominator));
}
};

Number n = 1;
Number r = Rational(3, 4);
Number t = ::boost::apply_visitor(plus_visitor(), n, r);
t is now 7/4

boost has a very nice documentation so look it up.
>
Another issue has to do with how to structure things around the
parsing. Bison uses unions for communication with flex so I have a
Number * in the union and whenever flex finds a rational or number,
allocates a new number and bison get's it so I can use it in parsing.
struct parsingState {
union {

Number *num;

};
ParsingStructureType type;
};
Problem is when I need to do some computations...
Guess I have Number *num; in the union and I want to update it to
become -num. I have defined operator-() in Number so I do:
parsingState ps;

...

ps->num = - ps->num;

It seems to be that this will leak right? (-ps->num) will allocate
another Number because operator-() is
Number Number::operator-() const;

and I'll lose my previous allocated number.
Any ideas on how I can do this or organize my structures?
Sorry I don't use nether Bison nor flex, can't help you there

Nov 21 '06 #2

P: n/a
I would simply store all numbers as rationals. Every integer N is also
special case of rational N/1.

Nov 21 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.