2011-03-23 18 views
7

me optimización de una consulta por calcular previamente algo de trigonometría-funnctions de los campos de una tabla, cuando me encontré con este:¿Error de MySQL? (Trigonometría)

SELECT 6371 * acos(0.793521289617132 * 0.793521289617132 + 0.608542490648241 * 0.608542490648241 * cos(0.235244203230056 - 0.235244203230056)) 

devuelva null

la consulta con valores no precalculado:

SELECT 6371 * acos(sin(radians(52.51581)) * sin(radians(52.51581)) + cos(radians(52.51581)) * cos(radians(g.lat)) * cos(radians(13.4785) - radians(13.4785))) 

devuelve 0 (que es el resultado correcto)

es esto un error? o se espera?

Respuesta

6

Usted tiene algunos errores de redondeo en su consulta que resulta de la aritmética flotante.

Si intenta esta consulta

SELECT -1 + (0.793521289617132 * 0.793521289617132 + 0.608542490648241 * 0.608542490648241 * cos(0.235244203230056 - 0.235244203230056)) 

obtendrá 6.66133814775094e-016. Así que lo que estamos tratando de hacer es

SELECT 6371 * acos(1 + 6.66133814775094e-016) 

que obviamente no funcionará porque acos solamente se define en el dominio [-1,1].

No sé qué es exactamente lo que intentas lograr, pero tienes que volver a trabajar tus cálculos, p. compruebe si el parámetro para acos está fuera de límites y luego establezca el valor en consecuencia, tal como este:

ACOS(IF(val BETWEEN -1 AND 1, val, SIGN(val)) 
+0

¡Gracias, eso tiene sentido! (Estoy calculando la distancia de gran círculo) – Dexter

4

ACOS devuelve NULL si X no está en el rango de -1 a 1

puede haber en el caso de valores no precalculado, MySQL está haciendo una cierta simplificación antes de aplicar ACOS

+0

que parece ser el caso, gracias! – Dexter