Quando si è un> un vero e proprio?
Domanda
A destra, penso che davvero sto vivendo un sogno. Ho il seguente pezzo di codice che ho compilato ed eseguito su una macchina 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;
}
Ora, il valore di 'un' dopo il calcolo viene segnalato come '1'. E, su questa macchina AIX, sembra che 1> 1 vale come il mio 'se' si immette !!! E le mie acos di quello che penso è '1' torna NaNq dal 1 è più grande di 1. Maggio chiedo come ciò sia possibile? Non so più cosa pensare!
Il codice funziona bene su altre architetture in cui 'a' davvero assume il valore di quello che penso è 1 e acos (a) è 0.
Soluzione
Se si fa un confronto in cui risultato e expctedResult sono tipi float:
if (result == expectedResult)
Quindi è improbabile che il confronto sarà vero. Se il confronto è vero, allora è probabilmente instabile -. Piccoli cambiamenti nei valori di input, compilatore, o CPU possono cambiare il risultato e fare il confronto essere false
Confronto con Epsilon - errore assoluto
if (fabs(result - expectedResult) < 0.00001)
Dalla confronto di numeri in virgola
galleggianteCiò che ogni computer Scientist dovrebbe conoscere circa virgola mobile aritmetica
Altri suggerimenti
Stampare i bit. Si potrebbe solo essere essere tratti in inganno da qualche errore di arrotondamento nella visualizzazione dei carri come numeri reali decimali.
La funzione printf , senza una precisione specificato, solo sarà vi mostrerà le prime 6 cifre. Quindi, provare a stampare con un più alto grado di precisione ... è possibile che a è leggermente più grande di 1, ma solo da un po '. Se si vuole fare le cose più robusta, al posto di (a> 1), è possibile utilizzare (a-1)> Epsilon per un valore di epsilon.
1,000000000000000000001 è maggiore di 1. Sei sicuro che appena sta non vedi cifre decimali abbastanza? Se tale controllo passa scommetto questo è il vostro problema.
La soluzione più comune è quella di utilizzare una qualche forma di Epsilon di fermarti preoccuparsi di errori di arrotondamento. vale a dire se il doppio avete dovrebbe essere quindi provare a fare
if ( a > 1.00001f )
La sua probabilmente abbastanza vicino a uno in modo da non causare problemi:)