我一直在尝试对为大地测量转换编写的C++类进行单元测试。

我注意到,三个变量的琐碎分组更改会极大地影响函数中的错误。

编辑:这是一个完整示例的完整功能:

假设latitudelongitudealtitude为零。 Earth::a = 6378137Earth::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不同?

最佳答案

您有不同的舍入,因为浮点不能代表所有数字:
a * b * c;(a * b) * c,可能与a * (b * c)不同。

您可能也有类似的问题。

附加示例:
10e10f + 1.f == 10e10f
所以(1.f + 10e10f) - 10e10f == 10e10f - 10e10f == 0.f1.f + (10e10f - 10e10f) == 1.f - 0.f == 1.f

关于c++ - 变量分组以优化的代码提供不同的答案,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21094590/

10-11 18:16