Вопрос

Правильно, я думаю, что я действительно живу мечтой. У меня есть следующий кусок кода, который я компилируемый и запущен на машине 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, он выглядит как 1> 1, верно, как мой «если» введен !!! И мои акусы того, что я думаю, это «1» возврат NANQ с 1 больше 1. Могу ли я спросить, как это даже возможно? Я не знаю, что больше думать!

Код работает нормально в других архитектурах, где «A» действительно принимает ценность того, что я думаю, 1 и ACOS (A) 0.

Это было полезно?

Решение

Если вы делаете сравнение, где результат и EXPCTEDEDRESULT являются типы поплавок:

if (result == expectedResult)

Тогда маловероятно, что сравнение будет правдой. Если сравнение верно, то, вероятно, нестабильно - крошечные изменения в входных значениях, компиляторе или процессоре могут изменить результат и сделать сравнение false.

Сравнение с Epsilon - абсолютная ошибка

if (fabs(result - expectedResult) < 0.00001)

От Сравнение номеров плавающих точек


Какой ученый компьютер должен знать о арифметике с плавающей точкой

Другие советы

Распечатайте биты. Возможно, вы просто одурачены некоторой ошибкой округления на дисплее плавающихся как десятичных действительных чисел.

То Printf. Функция без указанной точности будет отображаться только первые 6 цифр. Итак, попробуйте печать с более высокой степенью точности ... Возможно, что A немного больше 1, но только немного. Если вы хотите сделать вещи более надежными, вместо (A> 1) вы можете использовать (A-1)> Epsilon для некоторого значения epsilon.

1.00000000000000000000001 больше 1. Вы уверены, что вы просто не видите достаточно десятичных знаков? Если этот чек проходит, я бы парил, что ваша проблема.

Обычное решение - использовать некоторую форму EPSILON, чтобы остановить беспокоиться о ошибках округления. т.е. если удвоенный, который вы должны быть, то попробуйте сделать

if ( a > 1.00001f )

Это, вероятно, достаточно близко к одному, чтобы не причинить вам проблемы :)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top