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

Substitute 'float'?

P: n/a
Should it be possible to create a custom class, 'Float', which would behave
as a drop-in replacement for the builtin float type?

As mentioned in another thread, I once tried this in rather a hurry to try
and catch some floating point naughtiness, but was stumped in various
places. Is there a fundamental obstacle to doing this?

thanks,
G.A.
Jul 22 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
Glen Able wrote:
Should it be possible to create a custom class, 'Float', which would behave
as a drop-in replacement for the builtin float type?
Yes, basically.
As mentioned in another thread, I once tried this in rather a hurry to try
and catch some floating point naughtiness, but was stumped in various
places. Is there a fundamental obstacle to doing this?


Not that I can recall. Some would probably claim the legendary
performance decrease when using classes versus built-in types, but
IMO it's not always true. Given a good compiler and implementation
you should get the same performance.

V
Jul 22 '05 #2

P: n/a
Glen Able wrote:
Should it be possible to create a custom class, 'Float', which would behave
as a drop-in replacement for the builtin float type?

As mentioned in another thread, I once tried this in rather a hurry to try
and catch some floating point naughtiness, but was stumped in various
places. Is there a fundamental obstacle to doing this?
...


One fundamental obstacle that comes to mind is variadic functions.
Passing non-POD classes as variadic arguments results in udefined behavior.

Otherwise, it appears to be doable.

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #3

P: n/a
Glen Able posted:
Should it be possible to create a custom class, 'Float', which would
behave as a drop-in replacement for the builtin float type?

As mentioned in another thread, I once tried this in rather a hurry to
try and catch some floating point naughtiness, but was stumped in
various places. Is there a fundamental obstacle to doing this?

thanks,
G.A.


I don't understand, what do you mean by "a drop-in replacment"? Made me
think of:

typedef float Float;

Do you want to have a float which cannot contain certain values? Something
like:

class SpecialFloat
{
private:

float data;

public:

SpecialFloat& operator=(float input)
{
if (input != 666)
{
data = input;
}
}

operator float const()
{
return data;
}
};
Or maybe you're looking for something different altogether...
-JKop
Jul 22 '05 #4

P: n/a
Andrey Tarasevich wrote:
One fundamental obstacle that comes to mind is variadic functions.
Passing non-POD classes as variadic arguments results in udefined behavior.


I was not aware of that. Not that I write many variadic functions...

Good to know, nonetheless.
Jul 22 '05 #5

P: n/a
Julie wrote:
Andrey Tarasevich wrote:
One fundamental obstacle that comes to mind is variadic functions.
Passing non-POD classes as variadic arguments results in udefined
behavior.


I was not aware of that. Not that I write many variadic functions...


No, but you might have the idea to pass one of your objects to printf
one day. Another thing that comes to mind is conversions. The rules for
built-in types are different from the rules for user defined types.

Jul 22 '05 #6

P: n/a
Glen Able wrote:
Should it be possible to create a custom class, 'Float',
Is this a valid as a drop-in replacement for the builtin float type?
I have done this many times.

#include "Float.h"
#define float Float
As mentioned in another thread,
I once tried this in rather a hurry to try
and catch some floating point naughtiness,
but was stumped in various places.
Can you show us an example?
Is there a fundamental obstacle to doing this?


No.

The abstraction used in the C++ computer programming language
to define a portable "built-in" type float virtually guarantees
that you can substitute your own definition of float as long as
you implement the abstract data type defined by the standard.
Jul 22 '05 #7

P: n/a

"Glen Able" <sm*************@hotMEmail.com> wrote in message
news:cc*******************@news.demon.co.uk...
Should it be possible to create a custom class, 'Float', which would behave as a drop-in replacement for the builtin float type?

As mentioned in another thread, I once tried this in rather a hurry to try
and catch some floating point naughtiness, but was stumped in various
places. Is there a fundamental obstacle to doing this?

thanks,
G.A.


OK, I've had another go at implementing this...
Here's problem #1:

Clearly I need to have this constructor:

Float(float value) { m_value = value; }

But the existence of this means that any unions containing a 'Float' will be
invalid, whereas they were OK with 'float'.
Problem #2 seems more fundamental:

To allow sqrt etc. to work, I seem to require

operator float() { return m_value; }

Which causes massive problems of ambiguity regarding conversions.

By the way, would anyone else care to give this substitution a quick try on
their own code (so, define the Float class, then redefine float as Float)?
I think it'd be an interesting exercise to see what other issues this throws
up, especially since so many people seem to think this should be
unproblematic!

cheers,
G.A.
Jul 22 '05 #8

P: n/a
E. Robert Tisdale posted:

#define float Float

Disgusting.
We have:

inline functions
global const variables
typedefs
tempates

for a reason.
typedef float SpecialFloat;
Jul 22 '05 #9

P: n/a
Glen Able posted:

"Glen Able" <sm*************@hotMEmail.com> wrote in message
news:cc*******************@news.demon.co.uk...
Should it be possible to create a custom class, 'Float', which would
behave as a drop-in replacement for the builtin float type?

As mentioned in another thread, I once tried this in rather a hurry to
try and catch some floating point naughtiness, but was stumped in
various places. Is there a fundamental obstacle to doing this?

thanks,
G.A.

OK, I've had another go at implementing this...
Here's problem #1:

Clearly I need to have this constructor:

Float(float value) { m_value = value; }

But the existence of this means that any unions containing a 'Float'
will be invalid, whereas they were OK with 'float'.


No problem there. There'd be a problem with virtual functions though... but
ofcourse that isn't a virtual function.
union
{
SpecialFloat j;

int p;
} cow;
cow.p = 42;

cow.j = 45.6;


Problem #2 seems more fundamental:

To allow sqrt etc. to work, I seem to require

operator float() { return m_value; }

Which causes massive problems of ambiguity regarding conversions.

I don't see what you're on about. If a function wants a float:

SpecialFloat t;

Func(t);

What's wrong with that?

Or:

SpecialFloat k;
float t;

float r = k + t;

Again here, it's converted to a float
By the way, would anyone else care to give this substitution a quick
try on their own code (so, define the Float class, then redefine float
as Float)? I think it'd be an interesting exercise to see what other
issues this throws up, especially since so many people seem to think
this should be unproblematic!

cheers,
G.A.


Did my own example not show that? This is kindergarden stuff.
-JKop
Jul 22 '05 #10

P: n/a
JKop wrote:

Glen Able posted:

"Glen Able" <sm*************@hotMEmail.com> wrote in message
news:cc*******************@news.demon.co.uk...
Should it be possible to create a custom class, 'Float', which would
behave as a drop-in replacement for the builtin float type?

As mentioned in another thread, I once tried this in rather a hurry to
try and catch some floating point naughtiness, but was stumped in
various places. Is there a fundamental obstacle to doing this?

thanks,
G.A.


OK, I've had another go at implementing this...
Here's problem #1:

Clearly I need to have this constructor:

Float(float value) { m_value = value; }

But the existence of this means that any unions containing a 'Float'
will be invalid, whereas they were OK with 'float'.


No problem there. There'd be a problem with virtual functions though... but
ofcourse that isn't a virtual function.

union
{
SpecialFloat j;

int p;
} cow;


That's not legal. The constructor of SpecialFloat is non trivial and thus
SpecialFloat cannot be used inside a union.

Unfortunately the OP is correct. Using such a special class in a union
is almost always a problem. Luckily this case seldome arises in practice.

Problem #2 seems more fundamental:

To allow sqrt etc. to work, I seem to require

operator float() { return m_value; }

Which causes massive problems of ambiguity regarding conversions.


I don't see what you're on about. If a function wants a float:

SpecialFloat t;

Func(t);

What's wrong with that?


Creating such conversion operators needs to be done with
great care. By introducing them, you enable the compiler
to convert parameters even in cases where you don't want
them to happen. This is exactly the reason why eg. std::string
has no conversion operator to const char*, but a member function
c_str() instead.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #11

P: n/a
Karl Heinz Buchegger wrote:
To allow sqrt etc. to work, I seem to require

operator float() { return m_value; }

Which causes massive problems of ambiguity regarding conversions.


I don't see what you're on about. If a function wants a float:

SpecialFloat t;

Func(t);

What's wrong with that?


Creating such conversion operators needs to be done with
great care. By introducing them, you enable the compiler
to convert parameters even in cases where you don't want
them to happen. This is exactly the reason why eg. std::string
has no conversion operator to const char*, but a member function
c_str() instead.


To emphasize on that further.

Consider the following situation:

#include <iostream>
using namespace std;

class SpecialFloat
{
public:
SpecialFloat( float Val = 0.0f ) : m_Value( Val ) {};
float ToFloat() { return m_Value; }

friend SpecialFloat operator+( const SpecialFloat& lhs, const SpecialFloat& rhs );

private:
float m_Value;
};

SpecialFloat operator+( const SpecialFloat& lhs, const SpecialFloat& rhs )
{
return lhs.m_Value + rhs.m_Value;
}

int main()
{
SpecialFloat a( 1.0f );
float b;

b = ( a + 2.0f ).ToFloat();
}

All is well.
Then some clever programmer decides that the call of ToFloat is ugly, and that somebody
has to do something about it: introduce operator float():

#include <iostream>
using namespace std;

class SpecialFloat
{
public:
SpecialFloat( float Val = 0.0f ) : m_Value( Val ) {};
float ToFloat() { return m_Value; }

friend SpecialFloat operator+( const SpecialFloat& lhs, const SpecialFloat& rhs );

operator float() { return m_Value; }

private:
float m_Value;
};

SpecialFloat operator+( const SpecialFloat& lhs, const SpecialFloat& rhs )
{
return lhs.m_Value + rhs.m_Value;
}

int main()
{
SpecialFloat a( 1.0f );
float b;

b = a + 2.0f;
}

But now the whole thing no longer compiles.
Why?
Because the compiler now has to equally good ways to translate
b = a + 2.0f;

it could either

a) using the constructor, convert 2.0f to a SpecialFloat object and applying
the user defined operator+ on both SpecialFloat objects

or

b) convert a from SpecialFloat to an ordinary float by using the conversion
operator float() on a and using the builtin operator+ for floats.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #12

P: n/a
In message <Xv*****************@news.indigo.ie>, JKop <NU**@NULL.NULL>
writes
E. Robert Tisdale posted:

#define float Float

Disgusting.


Agreed. Redefining keywords is asking for trouble. It's probably also in
breach of 17.4.3.1.1.

We have:

inline functions
global const variables
typedefs
tempates

for a reason.
typedef float SpecialFloat;


But that doesn't satisfy the OP's requirement for a custom *class*.

--
Richard Herring
Jul 22 '05 #13

P: n/a
Karl Heinz Buchegger posted:

class SpecialFloat
{
public:
SpecialFloat( float Val = 0.0f ) : m_Value( Val ) {};


explicit SpecialFloat( float Val = 0.0f ) : m_Value( Val ) {};
Without spending too much time on the subject - I'm trying to get through
Bjarne's book.
Jul 22 '05 #14

P: n/a
JKop wrote:

Karl Heinz Buchegger posted:
class SpecialFloat
{
public:
SpecialFloat( float Val = 0.0f ) : m_Value( Val ) {};


explicit SpecialFloat( float Val = 0.0f ) : m_Value( Val ) {};


Then, with the example given, you can no longer write:
b = a + 2.0f;
Since the implicite constructor is no longer available.
The compiler chooses the way of converting b to a float
and does the addition by using the operator+ for builtin float
types. Thus the custom written operator+ is effectively useless
in this situation. You have to force the compiler to use it
by writing
b = a + SpecialFloat( 2.0f );
Not very intuitive.

When in doubt, I prefer implicite creation due the use
of constructors against implicit conversion with
conversion operators.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.