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は、1が1より大きいため、NanQを返します。それがどのように可能であるかを尋ねてもよいでしょうか。もう何を考えたらいいのかわからない!

このコードは、「a」が実際に1と思われる値を取り、acos(a)が0である他のアーキテクチャでも問題なく機能します。

4

4 に答える 4

8

resultとexpctedResultがfloatタイプである比較を行う場合:

if (result == expectedResult)

その場合、比較が真になる可能性は低くなります。比較がtrueの場合、おそらく不安定です。入力値、コンパイラ、またはCPUのわずかな変更によって結果が変更され、比較がfalseになる可能性があります。

イプシロンとの比較–絶対誤差

if (fabs(result - expectedResult) < 0.00001)

浮動小数点数の比較から


すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと

于 2010-04-30T10:17:46.960 に答える
4

ビットを印刷します。浮動小数点数を10進数の実数として表示する際の丸め誤差にだまされている可能性があります。

于 2010-04-30T10:07:45.043 に答える
4

printf関数は、精度が指定されていない場合、最初の6桁のみを表示します。したがって、より高い精度で印刷してみてください... aが1よりわずかに大きい可能性がありますが、少しだけです。(a> 1)の代わりに、物事をより堅牢にしたい場合は、イプシロンの値に(a-1)>イプシロンを使用できます。

于 2010-04-30T10:12:17.673 に答える
1

1.000000000000000000001は1より大きいです。小数点以下の桁数が足りないだけですか?そのチェックに合格した場合、私はあなたの問題を賭けます。

通常の解決策は、何らかの形式のイプシロンを使用して、丸め誤差の心配をなくすことです。つまり、ダブルにする必要がある場合は、実行してみてください

if ( a > 1.00001f )

問題を引き起こさないように、おそらく1に十分近いです:)

于 2010-04-30T10:11:01.743 に答える