Substitute 'float'?

Discussion in 'C++' started by Glen Able, Jul 8, 2004.

  1. Glen Able

    Glen Able Guest

    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.
     
    Glen Able, Jul 8, 2004
    #1
    1. Advertising

  2. 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
     
    Victor Bazarov, Jul 8, 2004
    #2
    1. Advertising

  3. 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
     
    Andrey Tarasevich, Jul 8, 2004
    #3
  4. Glen Able

    JKop Guest

    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
     
    JKop, Jul 8, 2004
    #4
  5. Glen Able

    Julie Guest

    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.
     
    Julie, Jul 8, 2004
    #5
  6. Glen Able

    Rolf Magnus Guest

    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.
     
    Rolf Magnus, Jul 8, 2004
    #6
  7. 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.
     
    E. Robert Tisdale, Jul 8, 2004
    #7
  8. Glen Able

    Glen Able Guest

    "Glen Able" <> wrote in message
    news:ccjusj$b4s$1$...
    > 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.
     
    Glen Able, Jul 9, 2004
    #8
  9. Glen Able

    JKop Guest

    E. Robert Tisdale posted:


    > #define float Float



    Disgusting.


    We have:

    inline functions
    global const variables
    typedefs
    tempates

    for a reason.


    typedef float SpecialFloat;
     
    JKop, Jul 9, 2004
    #9
  10. Glen Able

    JKop Guest

    Glen Able posted:

    >
    > "Glen Able" <> wrote in message
    > news:ccjusj$b4s$1$...
    >> 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
     
    JKop, Jul 9, 2004
    #10
  11. JKop wrote:
    >
    > Glen Able posted:
    >
    > >
    > > "Glen Able" <> wrote in message
    > > news:ccjusj$b4s$1$...
    > >> 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
     
    Karl Heinz Buchegger, Jul 9, 2004
    #11
  12. 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
     
    Karl Heinz Buchegger, Jul 9, 2004
    #12
  13. In message <XvvHc.4202$>, JKop <>
    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
     
    Richard Herring, Jul 9, 2004
    #13
  14. Glen Able

    JKop Guest

    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.
     
    JKop, Jul 9, 2004
    #14
  15. 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
     
    Karl Heinz Buchegger, Jul 9, 2004
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andy
    Replies:
    7
    Views:
    6,316
    Roedy Green
    May 10, 2004
  2. Jim West
    Replies:
    4
    Views:
    1,489
    Jeff Schwab
    Jan 16, 2004
  3. Jukka Lehtonen

    operator== (float, float)

    Jukka Lehtonen, Aug 4, 2004, in forum: C++
    Replies:
    5
    Views:
    2,450
    Jukka Lehtonen
    Aug 5, 2004
  4. bd
    Replies:
    0
    Views:
    659
  5. Carsten Fuchs
    Replies:
    45
    Views:
    1,627
    James Kanze
    Oct 8, 2009
Loading...

Share This Page