I’m trying to write good round_double function which will round double in specified precision:
1.
double round_double(double num, int prec)
{
for (int i = 0; i < abs(prec); ++i)
if(prec > 0)
num *= 10.0;
else
num /= 10.0;
double result = (long long)floor(num + 0.5);
for (int i = 0; i < abs(prec); ++i)
if(prec > 0)
result /= 10.0;
else
result *= 10.0;
return result;
}
2.
double round_double(double num, int prec)
{
double tmp = pow(10.0, prec);
double result = (long long)floor(num * tmp + 0.5);
result /= tmp;
return result;
}
This functions do what I wan’t but they are, in my opinion, not good enough. Because starting from precision = 13 – 14, they returning bad results.
The cause I’m sure that there is possible to write good double_round is that just printing the number via cout in specified precision (say 18) is prints better result than result of my function.
For example this part of code:
int prec = 18;
double num = 10.123456789987654321;
cout << setiosflags(ios::showpoint | ios::fixed)
<< setprecision(prec) << "round_double(" << num << ", "
<< prec << ") = " << round_double(num, prec) << endl;
Will print round_double(10.123456789987655000, 18) = -9.223372036854776500 for first round_double and round_double(10.123456789987655000, 18) = -9.223372036854776500for second one.
How write good round_double function in c++? Or there is already exists?
Don’t cast to
long longthat is forcing a conversion to an integer with limited range, beyond what 10^13 requires (well 19 for 64-bit with no whole number part). Just callingfloorshould be enough.Note that Mike is also correct, you have a limited range you can represent just in double itself. It isn’t so great if you need clean decimal responses. But the
long longis the cause of your totally wacky numbers.