2

是的,我想我真的在做梦。我有以下在 AIX 机器上编译和运行的代码:

AIX 3 5
PowerPC_POWER5 processor type
IBM XL C/C++ for AIX, V10.1
Version: 10.01.0000.0003


#include <stdio.h>
#include <math.h>

#define RADIAN(x) ((x) * acos(0.0) / 90.0)

double nearest_distance(double radius,double lon1, double lat1, double lon2, double lat2){
    double rlat1=RADIAN(lat1);
    double rlat2=RADIAN(lat2);
    double rlon1=lon1;
    double rlon2=lon2;
    double a=0,b=0,c=0;

    a = sin(rlat1)*sin(rlat2)+ cos(rlat1)*cos(rlat2)*cos(rlon2-rlon1);
    printf("%lf\n",a);
    if (a > 1) {
      printf("aaaaaaaaaaaaaaaa\n");
    }
    b = acos(a);
    c = radius * b;

    return radius*(acos(sin(rlat1)*sin(rlat2)+
        cos(rlat1)*cos(rlat2)*cos(rlon2-rlon1)));

}

int main(int argc, char** argv) {
  nearest_distance(6367.47,10,64,10,64);
  return 0;
}

现在,计算后的“a”值报告为“1”。而且,在这台 AIX 机器上,当输入我的“if”时,看起来 1 > 1 为真!!!我认为是 '1' 的 acos 返回 NanQ,因为 1 大于 1。请问这怎么可能?我不知道该怎么想了!

该代码在其他架构上工作得很好,其中“a”确实取我认为是 1 的值,而 acos(a) 是 0。

4

4 回答 4

8

如果您在 result 和 expctedResult 是浮点类型的情况下进行比较:

if (result == expectedResult)

那么这个比较不太可能是真的。如果比较结果为真,那么它可能是不稳定的——输入值、编译器或 CPU 的微小变化可能会改变结果并使比较结果为假。

与 epsilon 比较——绝对误差

if (fabs(result - expectedResult) < 0.00001)

比较浮点数


每个计算机科学家都应该知道的关于浮点运算的知识

于 2010-04-30T10:17:46.960 回答
4

打印出这些位。您可能只是被浮点数显示为十进制实数时的一些舍入错误所迷惑。

于 2010-04-30T10:07:45.043 回答
4

没有指定精度的printf函数只会显示前 6 位数字。因此,请尝试以更高的精度打印... a 可能略大于 1,但仅稍微大一点。如果你想让事情变得更健壮,而不是 (a>1),你可以使用 (a-1)>epsilon 来获得一些 epsilon 值。

于 2010-04-30T10:12:17.673 回答
1

1.000000000000000000001 大于 1。你确定你只是没有看到足够的小数位吗?如果那张支票通过了,我敢打赌那是你的问题。

通常的解决方案是使用某种形式的 epsilon 来避免您担心舍入错误。即如果你应该是双倍然后尝试做

if ( a > 1.00001f )

它可能足够接近一个,以免给您带来问题:)

于 2010-04-30T10:11:01.743 回答