Question

Bon, je pense que je suis vraiment vivre un rêve. Je le morceau de code suivant I compiler et exécuter sur une machine 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;
}

Maintenant, la valeur de « a » après le calcul est rapporté comme étant « 1 ». Et, sur cette machine AIX, il ressemble à 1> 1 est vrai que mon « si » est entré !!! Et mes ACOS de ce que je pense est « 1 » retours NaNq depuis 1 est plus grand que le 1er mai je demande comment cela est possible? Je ne sais pas quoi penser!

Le code fonctionne très bien sur d'autres architectures où « a » prend vraiment la valeur de ce que je pense est 1 et ACOS (a) est 0.

Était-ce utile?

La solution

  

Si vous faites une comparaison où résultat et expctedResult sont des types float:

if (result == expectedResult)
  

Ensuite, il est peu probable que la comparaison sera vrai. Si la comparaison est vrai, alors il est probablement instable -. Minuscules changements dans les valeurs d'entrée, compilateur, ou CPU peut changer le résultat et que la comparaison soit false

Comparaison avec epsilon - erreur absolue

if (fabs(result - expectedResult) < 0.00001)

De comparaison des nombres à virgule flottante


Ce que tout informaticien devrait savoir sur Virgule flottante Arithmétique

Autres conseils

Imprimez les bits. Vous pourriez être se laisser berner par une erreur d'arrondi dans l'affichage des flotteurs sous forme de nombres réels décimales.

La fonction printf , sans précision spécifiée, sera seulement vous montrer les 6 premiers chiffres. Alors, essayez d'imprimer avec une plus grande précision ... il est possible qu'un est légèrement plus grand que 1, mais seulement par un peu. Si vous voulez rendre les choses plus robustes, au lieu de (a> 1), vous pouvez utiliser (a-1)> epsilon pour une valeur de epsilon.

1,000000000000000000001 est supérieur à 1. Etes-vous sûr que vous venez de voir sont pas assez décimales? Si ce contrôle passe je parierais c'est votre problème.

La solution habituelle consiste à utiliser une certaine forme de epsilon pour vous empêcher de se soucier des erreurs d'arrondi. à savoir si la double vous devez être ensuite essayer de faire

if ( a > 1.00001f )

Son probablement assez proche de l'un pour ne pas vous causer des problèmes:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top