Jump to content
  • Advertisement
Sign in to follow this  
lemming77

Double and Float based fundamental types (vectors, matrices, etc.) implemented side by side?

This topic is 2337 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

As I'm sure is standard practice, I have written a library to implement types like vectors, matrices, and so on, and it all works quite nicely. However I have hit a hurdle.

Using D3D9 for graphics, that seems to like having it's data in the form of single precision floats. Which is fair enough. But I'm feeling the need to do some intense physics simulation using double precision. So what I really want is some means of implementing both without duplicating my entire library.

My current implementation lets me switch between Float and Double types before compiling by means of a typedef instruction. But this doesn't quite give me the solution I need, as I'm stuck choosing one over the other.

[source lang="cpp"]// The library is called Util. Not a great name, I know. Here's a small excerpt
// from Util.h. Define DOUBLE before compiling to use the double type.
// Otherwise, use the float type.

#ifdef DOUBLE
typedef double Real;
#define NAMESPACE Maths::Double
#else
typedef float Real;
#define NAMESPACE Maths
#endif

namespace Util {
namespace NAMESPACE {
struct Angle; // Euler angle
struct Matrix; // 4x4 Matrix
struct Quaternion;
struct Vector3;
}
}

// An excerpt from Vector3.h

namespace util {
namespace NAMESPACE {
// Vector3, 3D coordinates
struct Vector3 {
public:
Real x, y, z;

Vector3(); // x=0 y=0 z=0
Vector3(Real); // x=a y=a z=a
Vector3(Real, Real, Real); // x=a y=b z=c
/// ... Etc.
};
}[/source]

Can anyone recommend a means to implement both types into the same library? Preferably while duplicating as little source code as possible.

I'm using Visual C++ 2010 Express. Thanks smile.png Edited by lemming77

Share this post


Link to post
Share on other sites
Advertisement
How about using templates to achieve this? It's fast and easy, and you could even expand your vector class even further with other primitive types if you would ever need to do so.

Share this post


Link to post
Share on other sites
As mentioned above, templates are just the right tool to use for your task.
In particular, class templates -- here's a tutorial with (plenty of) examples: http://cppannotations.sourceforge.net/cppannotations/html/cplusplus21.html#l451

Share this post


Link to post
Share on other sites
Templates do seem like a nice solution, although I can't help but wonder whether it's a bit overkill, since there's only the two versions of each I need. :P Are there any other ways I could do this for comparison?

Share this post


Link to post
Share on other sites
What's so overkill about it?
Basically, you replace 7 lines of code
[source lang="cpp"]
#ifdef DOUBLE
typedef double Real;
#define NAMESPACE Maths::Double
#else
typedef float Real;
#define NAMESPACE Maths
#endif
[/source]
with one* line of code
[source lang="cpp"]
template <typename Real>
[/source]
-- looks like less of an overkill to what it started as ;-)

* -- sure, you have to do that for each of { struct Angle; struct Matrix; struct Quaternion; struct Vector3; } -- that's still just 4 (< 7) lines of code, though :-)
And you don't need the separate-namespace-per-type complexity anymore, since, say Angle<float> and Angle<double> are unambiguously distinct types.

If for some reason you insist on the implementation that only lets you switch between floating-point types (and nothing else, refusing to compile for other kinds of types) you can easily achieve that with std::enable_if combined with std::is_floating_point:
http://en.cppreference.com/w/cpp/types/enable_if // see the "class A" example
http://en.cppreference.com/w/cpp/types/is_floating_point Edited by Matt-D

Share this post


Link to post
Share on other sites
I hadn't thought of it like that. I just assumed that templates came with a huge level of extra functionality which was going to waste.

I've done some experiments, and I think you're right. I really like how the template solution has worked out so far. I want to play around with it some more first, to better get to know it. But it's looking very likely that's the way I'll go!

Thank you for the help! :)

Share this post


Link to post
Share on other sites
I'm using bunch of typedefs in addition to templates:

typedef vector<float,2> vector2f;
typedef vector<float,3> vector3f;
typedef vector<float,4> vector4f;
typedef vector<double,2> vector2d;
typedef vector<double,3> vector3d;
typedef vector<double,4> vector4d;

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!