I have the following codes to cast a double
into an int
:
double dblValue = 7.30;
int intValue = (int)(dblValue*100); //I want intValue to store extactly 730;
cout << intValue;
Output: 729
I know that the compiler is reading dblValue as 7.2999999 before casting it to int.
My question is: Is it possible to cast it as 730 by preventing the round down errors?
It would be best if your solution avoid using C++11 or other predefined functions. The only pre-processor directive I am using here is <iostream>
.
You cannot prevent rounding errors when converting a number that is not an integer (in the mathematical sense) to an integer, the only thing you can do is try to achieve proper rounding.
The easiest way to achieve a sensible (although not perfect) rounding is the following:
int intValue = (int)(dblValue < 0 ? dblValue - 0.5 : dblValue + 0.5);
And of course, since your question is tagged both c++
and casting
I cannot resist replacing your c-style cast with a c++ style cast:
int intValue = static_cast<int>(dblValue < 0 ? dblValue - 0.5 : dblValue + 0.5);
You can define your own integer truncation function that increases the value by the smallest possible amount, to make sure the rounded result is over the integer threshold.
#include <limits>
int int_cast(double x)
{
return (int)(x * (1.0 + std::numeric_limits<double>::epsilon()));
}
If you don't want to depend on <limits>
you can use DBL_EPSILON
from <float.h>
or substitute your own very small number. See also this question.
It's not any type of error, it's the way computer stores floating-point values.
You can do something like this:
int intValue = (int)(dblValue*100 + 0.00001);
C++11 added lround that helps to avoid precision loss on implicit double to long truncating cast:
int intValue = (int) lround(dblValue*100)
long
to int
cast won't loose precision too.
There is no iround()
, unfortunately.
Update
I guess there is no iround()
because any 32-bit integer will allways fit completely in 52 precision bits of 64-bit double. So there is no chance of precision loss on direct double to int truncation:
int intValue = (int) round(dblValue*100)