How to tackle this problem???

P

Paulo Matos

Hi all,

I'm doing some numerical computations with integers, rationals (from
boost), floating point numbers, etc. I'm defining ints as long int,
rationals (boost class), and floating point are doubles. I'm creating
an interface to these types called just 'number', so that I don't need
to worry with conversions, exactness, etc.

Initial approach was something like:
class number {
public:
....

private:
enum type {INT, FLOAT, RAT};

union {
long inum;
double fnum;
rational<long> rnum;
};

type t;
.....
};

Problem is rational has constructors, which are disallowed in union.
Another way would be to have number as abstract base class and then
have 3 derived classes, one for each type but that seems too cumbersome
and I would like to avoid inheritance in this case. I could also have a
pointer to a rational instead of a rational but during thousands and
thousands of computations I guess having a pointer to a rational and
constantly mallocing and deleting it is a performance nightmare. Yet
another solution would be to forget the union and to waste space by
having all three datatypes outside an union but at any time using only
the one to which the type refers to.

I'm open to ideas, suggestions and comments.

Thanks in advance,

Paulo Matos
 
I

Ivan Vecerina

: I'm doing some numerical computations with integers, rationals (from
: boost), floating point numbers, etc. I'm defining ints as long int,
: rationals (boost class), and floating point are doubles. I'm creating
: an interface to these types called just 'number', so that I don't need
: to worry with conversions, exactness, etc.

How does your class help with this?
What kind of implicit conversions does it provide?
When a rational is multiplied by a double, I think that
there isn't a good choice to provide an exact result.

: Initial approach was something like:
: class number {
: public:
: ...
:
: private:
: enum type {INT, FLOAT, RAT};
:
: union {
: long inum;
: double fnum;
: rational<long> rnum;
: };
:
: type t;
: ....
: };
:
: Problem is rational has constructors, which are disallowed in union.
: [....] I could also have a
: pointer to a rational instead of a rational but during thousands and
: thousands of computations I guess having a pointer to a rational and
: constantly mallocing and deleting it is a performance nightmare. Yet
: another solution would be to forget the union and to waste space by
: having all three datatypes outside an union but at any time using only
: the one to which the type refers to.
:
: I'm open to ideas, suggestions and comments.

If run-time execution speed is a concern, you'll probably be better
off using "double" everywhere, rather than a wrapper class. Or -
depending on the intended usage - use template functions that accept
parameters of either type.

If you really needed to implement the above design using
boost::rational and without any memory indirection, it would be
possible to store a dummy type within the union, and to manually
construct/destruct the "rational" field in-place (using placement-
new and explicit destructor calls). But is it worth the effort?
The alternative being to re-implement "rational" within your class...


hth -Ivan
 
P

Paulo Matos

Ivan said:
: I'm doing some numerical computations with integers, rationals (from
: boost), floating point numbers, etc. I'm defining ints as long int,
: rationals (boost class), and floating point are doubles. I'm creating
: an interface to these types called just 'number', so that I don't need
: to worry with conversions, exactness, etc.

How does your class help with this?
What kind of implicit conversions does it provide?
When a rational is multiplied by a double, I think that
there isn't a good choice to provide an exact result.

Although I admit such class is general not necessary, or even
recommendable, it's highly interesting in my case where I want to
provide true abstraction between number types without worrying about
what these numbers are.
: Initial approach was something like:
: class number {
: public:
: ...
:
: private:
: enum type {INT, FLOAT, RAT};
:
: union {
: long inum;
: double fnum;
: rational<long> rnum;
: };
:
: type t;
: ....
: };
:
: Problem is rational has constructors, which are disallowed in union.
: [....] I could also have a
: pointer to a rational instead of a rational but during thousands and
: thousands of computations I guess having a pointer to a rational and
: constantly mallocing and deleting it is a performance nightmare. Yet
: another solution would be to forget the union and to waste space by
: having all three datatypes outside an union but at any time using only
: the one to which the type refers to.
:
: I'm open to ideas, suggestions and comments.

If run-time execution speed is a concern, you'll probably be better
off using "double" everywhere, rather than a wrapper class. Or -
depending on the intended usage - use template functions that accept
parameters of either type.

double is definetely not good, although I admit it's good
_performance_wise_. That's what I am using. However, the need for exact
rationals and the common use of integers just made think this class
could be worth it!
If you really needed to implement the above design using
boost::rational and without any memory indirection, it would be
possible to store a dummy type within the union, and to manually
construct/destruct the "rational" field in-place (using placement-
new and explicit destructor calls). But is it worth the effort?
The alternative being to re-implement "rational" within your class...

What do you mean 'construct/destruch the "rational" field in-place'. It
seems I didn't quite get it!
 
T

Thomas Tutone

Paulo said:
I'm doing some numerical computations with integers, rationals (from
boost), floating point numbers, etc. I'm defining ints as long int,
rationals (boost class), and floating point are doubles. I'm creating
an interface to these types called just 'number', so that I don't need
to worry with conversions, exactness, etc.

Initial approach was something like:
class number {
public:
...

private:
enum type {INT, FLOAT, RAT};

union {
long inum;
double fnum;
rational<long> rnum;
};

type t;
....
};

Problem is rational has constructors, which are disallowed in union.
Another way would be to have number as abstract base class and then
have 3 derived classes, one for each type but that seems too cumbersome
and I would like to avoid inheritance in this case. I could also have a
pointer to a rational instead of a rational but during thousands and
thousands of computations I guess having a pointer to a rational and
constantly mallocing and deleting it is a performance nightmare.
Yet
another solution would be to forget the union and to waste space by
having all three datatypes outside an union but at any time using only
the one to which the type refers to.

Memory is cheap. Do you really care that you're wasting space by
having the three datatypes outside a union? Remember, the simplest
solution is often the best one. Try it that way and see if it serves
your purposes.

Good luck.

Best regards,

Tom
 
Z

Zara

Hi all,

I'm doing some numerical computations with integers, rationals (from
boost), floating point numbers, etc. I'm defining ints as long int,
rationals (boost class), and floating point are doubles. I'm creating
an interface to these types called just 'number', so that I don't need
to worry with conversions, exactness, etc.

Initial approach was something like:
class number {
public:
...

private:
enum type {INT, FLOAT, RAT};

union {
long inum;
double fnum;
rational<long> rnum;
};

type t;
....
};

Problem is rational has constructors, which are disallowed in union.
Another way would be to have number as abstract base class and then
have 3 derived classes, one for each type but that seems too cumbersome
and I would like to avoid inheritance in this case. I could also have a
pointer to a rational instead of a rational but during thousands and
thousands of computations I guess having a pointer to a rational and
constantly mallocing and deleting it is a performance nightmare. Yet
another solution would be to forget the union and to waste space by
having all three datatypes outside an union but at any time using only
the one to which the type refers to.

I'm open to ideas, suggestions and comments.

If you are already using a boost library, you may consider using
boost::variant instead of a union

Zara
 
I

Ivan Vecerina

: > If you really needed to implement the above design using
: > boost::rational and without any memory indirection, it would be
: > possible to store a dummy type within the union, and to manually
: > construct/destruct the "rational" field in-place (using placement-
: > new and explicit destructor calls). But is it worth the effort?
: > The alternative being to re-implement "rational" within your class...
: >
:
: What do you mean 'construct/destruch the "rational" field in-place'. It
: seems I didn't quite get it!
Basic idea (using a local variable instead of a data member):
#include <new> // for standard placement-new operator
typedef rational<long> T; // for this demo
unsigned char storage[ sizeof(T) ] //KV: check alignment too
T& var = * new (storage) T; // constructs a T in the storage array

... var is a reference to a valid rational, can be used as such
//KV: if an exception is thrown, ~T() is not called automatically

var.~T(); // explicitly call destructor.

I do not remember the implementation of boost::variant: it will be
using a similar technique if it shares storage among possible
"members". But it might be using indirection (pointer to
heap-allocated instance) instead.

Again, this is too complex to be worth the effort IMO.

Cheers,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,211
Messages
2,571,100
Members
47,695
Latest member
KayleneBee

Latest Threads

Top