次の関数を検討してください。
#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;
}
私のマシンでは、次のように返されます。
0.000000000000000e+00
-1.806765794754028e-07
(0, 0) の代わりに。2 番目の式には大きな丸め誤差があります。
私の質問は、型を変更せずに各関数の丸め誤差を減らす方法です (これらの 2 つの関数宣言を保持する必要があります (ただし、式は再配置できます): それらはより大きなプログラムからのものです)。