468,504 Members | 2,003 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,504 developers. It's quick & easy.

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

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

Oct 19 '06 #1
11 5219
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.
Oct 19 '06 #2
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
Oct 19 '06 #3
Philipp Reh <se**@s-e-f-i.dewrote:
>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
Oct 19 '06 #4
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
Oct 19 '06 #5
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
Oct 19 '06 #6

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.

Oct 19 '06 #7
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
cl*******@gmail.com
Oct 20 '06 #8
On Thu, 19 Oct 2006 11:55:55 -0400, Bo Peng <bp***@rice.eduwrote 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/~a...FAQ-acllc.html
Oct 20 '06 #9
Jack Klein <ja*******@spamcop.netwrote:
>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
Oct 20 '06 #10
Jack Klein wrote:
On Thu, 19 Oct 2006 11:55:55 -0400, Bo Peng <bp***@rice.eduwrote 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
cl*******@gmail.com
Oct 20 '06 #11
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
Oct 20 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.