我一直试图对我为大地变换写的C++
课进行单元测试。
我注意到三个变量的微小分组变化极大地影响了函数中的误差。
编辑:以下是可编译示例的完整功能:
假设latitude
,longitude
和altitude
为零。 Earth::a = 6378137
和Earth::b = 6356752.3
我正在努力获取基准数据,今天出现了一些问题,我不得不这样做。
void Geodesy::Geocentric2EFG(double latitude, double longitude, double altitude, double *E, double *F, double *G) {
double a2 = pow<double>(Earth::a, 2);
double b2 = pow<double>(Earth::b, 2);
double radius = sqrt((a2 * b2)/(a2 * pow<double>(sin(latitude), 2) + b2 * pow<double>(cos(longitude), 2)));
radius += altitude;
*E = radius * (cos(latitude) * cos(longitude));
*F = radius * (cos(latitude) * sin(longitude));
*G = radius * sin(latitude);
return;
}
所有值都定义为double
,包括Earth
中的值。 pow<T>()
函数是由以下内容定义的递归模板函数:
template <typename T>
static inline T pow(const T &base, unsigned const exponent) {
return (exponent == 0) ? 1 : (base * pow(base, exponent - 1));
}
有问题的代码:
*E = radius * cos(latitude) * cos(longitude);
*F = radius * cos(latitude) * sin(longitude);
产生的结果与:
不同*E = radius * (cos(latitude) * cos(longitude));
*F = radius * (cos(latitude) * sin(longitude));
编译器在gcc
中使用优化级别3
执行哪些操作才能使这些结果1e-2
不同?
答案 0 :(得分:2)
您有不同的舍入,因为浮点不能代表所有数字:
a * b * c;
为(a * b) * c
,可能与a * (b * c)
不同。
您也可能遇到类似的问题。
添加示例:
10e10f + 1.f == 10e10f
所以(1.f + 10e10f) - 10e10f == 10e10f - 10e10f == 0.f
而1.f + (10e10f - 10e10f) == 1.f - 0.f == 1.f
。