Is static_cast<int>(static_cast<double>(a)) == a?

Discussion in 'C++' started by Bo Peng, Oct 19, 2006.

  1. Bo Peng

    Bo Peng Guest

    Dear C++ experts,

    I need to store and retrieve a meta information that can be int or
    double. The program would be significantly simpler if I can handle two
    types uniformly. Right now, I am using a single interface:

    void setInfo(double); // store info
    double info(); // retrieve info

    and use
    setInfo(static_cast<double>(a))
    and
    static_cast<int>(info())

    to save and retrieve integers. I have not seen any problem yet but I am
    worried that maybe sometimes, 12 can be saved as 11.99999999 and
    retrieved as 11.

    Many thanks in advance.
    Bo
    Bo Peng, Oct 19, 2006
    #1
    1. Advertising

  2. Bo Peng

    Philipp Reh Guest

    On Thu, 19 Oct 2006 11:55:55 -0400, Bo Peng wrote:

    > Dear C++ experts,
    >
    > I need to store and retrieve a meta information that can be int or
    > double. The program would be significantly simpler if I can handle two
    > types uniformly. Right now, I am using a single interface:
    >
    > void setInfo(double); // store info
    > double info(); // retrieve info
    >
    > and use
    > setInfo(static_cast<double>(a))
    > and
    > static_cast<int>(info())
    >
    > to save and retrieve integers. I have not seen any problem yet but I am
    > worried that maybe sometimes, 12 can be saved as 11.99999999 and
    > retrieved as 11.
    >
    > Many thanks in advance.
    > Bo


    Hi,

    the representation of double in C++ is completly implementation defined
    and so is the conversion from double to int.

    If you need to handle types uniformly but you need just one type at a time
    use a variant. boost::variant can help here.
    Philipp Reh, Oct 19, 2006
    #2
    1. Advertising

  3. Bo Peng wrote:
    > I need to store and retrieve a meta information that can be int or
    > double. The program would be significantly simpler if I can handle two
    > types uniformly. Right now, I am using a single interface:
    >
    > void setInfo(double); // store info
    > double info(); // retrieve info
    >
    > and use
    > setInfo(static_cast<double>(a))


    There is no need for the static_cast here.

    > and
    > static_cast<int>(info())
    >
    > to save and retrieve integers. I have not seen any problem yet but I
    > am worried that maybe sometimes, 12 can be saved as 11.99999999 and
    > retrieved as 11.


    Unless your integers have more digits than your double can represent,
    you have nothing to worry about. In a usual system nowadays, 'double'
    (which has 16 digits of precision) can represent _any_ 'int' (which
    has only 10 digits. If you want to check, you can write a simple
    program that counts all integers from INT_MIN to INT_MAX and if the
    condition you put in the subject line is not satisfied, report back.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Oct 19, 2006
    #3
  4. Bo Peng

    Steve Pope Guest

    Philipp Reh <> wrote:

    >the representation of double in C++ is completly implementation defined
    >and so is the conversion from double to int.


    I think this is a little misleading, especially the second
    half of the statement. A double value which represents an
    exact integer must be converted to that integer in any implementation.

    The representation of doubles is implementation-dependent as you
    state, but if you can ensure that IEEE floating point double precision
    is being used, then a large range of integers are precisely represented.

    This is reliable enough such that some languages (matlab, perl)
    do not bother to have a separate integer type.

    Steve
    Steve Pope, Oct 19, 2006
    #4
  5. Bo Peng

    Bo Peng Guest

    > Unless your integers have more digits than your double can represent,
    > you have nothing to worry about. In a usual system nowadays, 'double'
    > (which has 16 digits of precision) can represent _any_ 'int' (which
    > has only 10 digits. If you want to check, you can write a simple
    > program that counts all integers from INT_MIN to INT_MAX and if the
    > condition you put in the subject line is not satisfied, report back.


    The following code does not report any problem so I guess I can relax?
    This is gor gcc/linux only though.

    #include <iostream>

    int main()
    {
    for(int i=-INT_MAX; i < INT_MAX; ++i)
    if( static_cast<int>(static_cast<double>(i)) != i)
    std::cout << i << " is in trouble\n";
    }

    Cheers,
    Bo
    Bo Peng, Oct 19, 2006
    #5
  6. Bo Peng

    Bo Peng Guest

    Steve Pope wrote:
    > A double value which represents an
    > exact integer must be converted to that integer in any implementation.
    > The representation of doubles is implementation-dependent as you
    > state, but if you can ensure that IEEE floating point double precision
    > is being used, then a large range of integers are precisely represented.


    This is good to know. Maybe this is somewhere in the C/C++ standard.

    > This is reliable enough such that some languages (matlab, perl)
    > do not bother to have a separate integer type.


    OK. If matlab and perl can take the risk, so can I. :)

    Thank you very much for your informative and quick reply.

    Bo
    Bo Peng, Oct 19, 2006
    #6
  7. Bo Peng

    Noah Roberts Guest

    Bo Peng wrote:
    > Dear C++ experts,
    >
    > I need to store and retrieve a meta information that can be int or
    > double. The program would be significantly simpler if I can handle two
    > types uniformly. Right now, I am using a single interface:
    >
    > void setInfo(double); // store info
    > double info(); // retrieve info
    >
    > and use
    > setInfo(static_cast<double>(a))
    > and
    > static_cast<int>(info())
    >
    > to save and retrieve integers. I have not seen any problem yet but I am
    > worried that maybe sometimes, 12 can be saved as 11.99999999 and
    > retrieved as 11.


    Float creep. Yes, it happens. You can get values that bounce around,
    slide left/right, etc... Most implementations seem to handle the
    particular case you are talking about ok but the problem still exists
    and can cause issues in other areas.
    Noah Roberts, Oct 19, 2006
    #7
  8. Bo Peng wrote:
    >> Unless your integers have more digits than your double can represent,
    >> you have nothing to worry about. In a usual system nowadays, 'double'
    >> (which has 16 digits of precision) can represent _any_ 'int' (which
    >> has only 10 digits. If you want to check, you can write a simple
    >> program that counts all integers from INT_MIN to INT_MAX and if the
    >> condition you put in the subject line is not satisfied, report back.

    >
    > The following code does not report any problem so I guess I can relax?
    > This is gor gcc/linux only though.
    >
    > #include <iostream>
    >
    > int main()
    > {
    > for(int i=-INT_MAX; i < INT_MAX; ++i)
    > if( static_cast<int>(static_cast<double>(i)) != i)
    > std::cout << i << " is in trouble\n";
    > }


    Then you are likely OK for that particular platform, but remember to
    re-check this anytime you build for a different compiler/OS/processor
    combination (for instance, this will not work on a platform where int
    and double are both 64-bits).

    --
    Clark S. Cox III
    Clark S. Cox III, Oct 20, 2006
    #8
  9. Bo Peng

    Jack Klein Guest

    On Thu, 19 Oct 2006 11:55:55 -0400, Bo Peng <> wrote in
    comp.lang.c++:

    > Dear C++ experts,
    >
    > I need to store and retrieve a meta information that can be int or
    > double. The program would be significantly simpler if I can handle two
    > types uniformly. Right now, I am using a single interface:
    >
    > void setInfo(double); // store info
    > double info(); // retrieve info
    >
    > and use
    > setInfo(static_cast<double>(a))
    > and
    > static_cast<int>(info())
    >
    > to save and retrieve integers. I have not seen any problem yet but I am
    > worried that maybe sometimes, 12 can be saved as 11.99999999 and
    > retrieved as 11.
    >
    > Many thanks in advance.
    > Bo


    You've received a lot of answers containing guesses. The C++ standard
    inherits <float.h> (or <cfloat>) from C, and it defines macros
    FLT_DIG, DBL_DIG, and LDBL_DIG that provide the guarantees you are
    asking for for the three floating point types.

    Since the minimum value for FLT_DIG is 6, and the minimum for the
    others is 10, any integer value in the range of +/- 9,999,999,999,999
    may be stored in a float and later back into a (wide enough) integer
    type and yield the exact value.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Oct 20, 2006
    #9
  10. Bo Peng

    Steve Pope Guest

    Jack Klein <> wrote:

    >You've received a lot of answers containing guesses. The C++ standard
    >inherits <float.h> (or <cfloat>) from C, and it defines macros
    >FLT_DIG, DBL_DIG, and LDBL_DIG that provide the guarantees you are
    >asking for for the three floating point types.


    >Since the minimum value for FLT_DIG is 6, and the minimum for the
    >others is 10, any integer value in the range of +/- 9,999,999,999,999
    >may be stored in a float and later back into a (wide enough) integer
    >type and yield the exact value.


    Cool. Thanks.

    Steve
    Steve Pope, Oct 20, 2006
    #10
  11. Jack Klein wrote:
    > On Thu, 19 Oct 2006 11:55:55 -0400, Bo Peng <> wrote in
    > comp.lang.c++:
    >
    >> Dear C++ experts,
    >>
    >> I need to store and retrieve a meta information that can be int or
    >> double. The program would be significantly simpler if I can handle two
    >> types uniformly. Right now, I am using a single interface:
    >>
    >> void setInfo(double); // store info
    >> double info(); // retrieve info
    >>
    >> and use
    >> setInfo(static_cast<double>(a))
    >> and
    >> static_cast<int>(info())
    >>
    >> to save and retrieve integers. I have not seen any problem yet but I am
    >> worried that maybe sometimes, 12 can be saved as 11.99999999 and
    >> retrieved as 11.
    >>
    >> Many thanks in advance.
    >> Bo

    >
    > You've received a lot of answers containing guesses. The C++ standard
    > inherits <float.h> (or <cfloat>) from C, and it defines macros
    > FLT_DIG, DBL_DIG, and LDBL_DIG that provide the guarantees you are
    > asking for for the three floating point types.
    >
    > Since the minimum value for FLT_DIG is 6, and the minimum for the
    > others is 10, any integer value in the range of +/- 9,999,999,999,999
    > may be stored in a float and later back into a (wide enough) integer
    > type and yield the exact value.


    That is certainly not true. With 6 digits of precision, a float can not
    accurately represent integers in the range of a 32-bit integer (a 16-bit
    integer would be fine). With 10 digits, of precision a double can
    represent all of the integers in a 32-bit integer, but not a 64-bit integer.


    --
    Clark S. Cox III
    Clark S. Cox III, Oct 20, 2006
    #11
  12. Jack Klein wrote:
    > [...]
    > Since the minimum value for FLT_DIG is 6, and the minimum for the
    > others is 10, any integer value in the range of +/- 9,999,999,999,999
    > may be stored in a float and later back into a (wide enough) integer
    > type and yield the exact value.


    Uh... How do you arrive at that conclusion? First of all, "the range
    of +/- 9,999,999,999,999" requires 13 digits of precision. We could
    dismiss that as a typo, of course, but then, you say "stored in a float"
    when you should probably say "stored in a double".

    And shouldn't we actually be using 'std::numeric_limits' instead?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Oct 20, 2006
    #12
    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. Sydex
    Replies:
    12
    Views:
    6,485
    Victor Bazarov
    Feb 17, 2005
  2. Schnoffos
    Replies:
    2
    Views:
    1,208
    Martien Verbruggen
    Jun 27, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,629
    Old Wolf
    Jan 20, 2004
  4. Shriramana Sharma
    Replies:
    8
    Views:
    273
    Gerhard Fiedler
    Jun 18, 2013
  5. junyangzou
    Replies:
    13
    Views:
    257
Loading...

Share This Page