Consider the following functions:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <limits>
template <typename Type>
inline Type a(const Type dx, const Type a0, const Type z0, const Type b1)
{
return (std::sqrt(std::abs(2*b1-z0))*dx)+a0;
}
template <typename Type>
inline Type b(const Type dx, const Type a0, const Type z0, const Type a1)
{
return (std::pow((a1-a0)/dx, 2)+ z0)/2;
}
int main(int argc, char* argv[])
{
double dx = 1.E-6;
double a0 = 1;
double a1 = 2;
double z0 = -1.E7;
double b1 = -10;
std::cout<<std::scientific;
std::cout<<std::setprecision(std::numeric_limits<double>::digits10);
std::cout<<a1-a(dx, a0, z0, b(dx, a0, z0, a1))<<std::endl;
std::cout<<b1-b(dx, a0, z0, a(dx, a0, z0, b1))<<std::endl;
return 0;
}
On my machine, it returns:
0.000000000000000e+00
-1.806765794754028e-07
Instead of (0, 0). There is a large rounding error with the second expression.
My question is: how to reduce the rounding error of each function without changing the type (I need to keep these 2 functions declarations (but the formulas can be rearanged): they come from a larger program)?